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?
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 .
The (void) indicates the return type. This method doesn't return anything, so its result can't be assigned to anything.
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.
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.
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!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With