Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obj-C: C functions declared inside or outside @implementation block, what's the difference?

what's the difference between a C function (static or not) declared inside or outside the implementation block (@implementation ... @end) of a Objective-C class?

is this specially true?:

If you need to poke inside of the object directly, you can put this function inside of the @implementation block of your class, and then you can access instance variables with the C arrow operator. But that’s kind of naughty, so to preserve your Purity of Essence you should be using method calls on your object. End of Sermon. Here’s the evil:

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
dealie->_frognatz = [NSColor plaidColor];
// and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid

can i access instance variables of my class within functions (declared in the same class) in this way?

like image 630
jlpiedrahita Avatar asked Jun 22 '09 17:06

jlpiedrahita


People also ask

What is an Objective C block?

Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary .

What does void mean in Objective C?

The (void) indicates the return type. This method doesn't return anything, so its result can't be assigned to anything.

What are methods in Objective C?

Basically in Objective-C, we call the function as method. The Objective-C foundation framework provides numerous built-in methods that your program can call. For example, method appendString() to append string to another string. A method is known with various names like a function or a sub-routine or a procedure, etc.


2 Answers

While this is legal, I don't understand why it's required in the kind of case you've described (and it is an ugly solution). Why can't you just call:

[dealie setFrognatz:[NSColor plaidColor]];

If you don't usually provide a -setFrognatz:, just make it a private method by declaring it inside the .m, but above this function definition. (It doesn't actually matter if it's in the @implementation block in this case.)

@interface BWOblateSphereoid ()
- (void)setFrognatz:(NSColor *)acolor
@end

@implementation OblateSphereoid

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData)
{
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData;
    [dealie setFrognatz:[NSColor plaidColor]];
    // and more stuff.
} // drawEggThunk

...
@end // OblateSphereoid

There are a few places where -> notation can be helpful. The most critical is in implementing -copyWithZone: where it can be absolutely required (a requirement that really emphasizes why I hate any ObjC code that plays with raw memory like NSCopyObject() does). But I recommend against -> in most cases for the same reasons I always recommend accessors. Even in the case where you need to pass an ivar by reference to a C function (another common use of ->), I prefer using a temporary and then assigning it afterwards.

I consider the fact that ivars are not @private by default to be a bug in ObjC.... I put @private at the top of every @interface block and have avoided several nasty bugs that way.

BTW, your solution as written may be leaking an NSColor. Maybe it is, maybe it's not, but an accessor would be certain.

like image 184
Rob Napier Avatar answered Nov 05 '22 07:11

Rob Napier


This will work fine if its inside your @implementation. I'd recommend you make it a normal method, but it works.

If you put it out of your implementation, you get this warning: Warning: instance variable '' is @protected; this will be a hard error in the future. You can avoid this error by putting a @public before your iVar in the header... like so:

@public 
int myInt;

That allows you to access the variables like a C (pointer) Struct wherever the object appears without warning.

So its doable, not recommended though!!!

like image 21
micmoo Avatar answered Nov 05 '22 07:11

micmoo