Rasto
Rasto

Reputation: 17774

Is property getter called even if I access property by name?

Let's say that I declare property in following way:

@property(nonatomic, strong, getter = isWorking) BOOL working;

Then instead of having the property to be synthesized I write the getter myself (and add some custom logic to it).

What will happen if I access the property in following way:

BOOL work = self.working;

Is the getter (and my custom logic there) still called or is it called only when I access the property using getter explicitly (BOOL work = self.isWorking;) ?

Upvotes: 1

Views: 148

Answers (1)

cHao
cHao

Reputation: 86504

Oops. Just tried it. Apparently i use dot notation too much, and didn't realize just how much it was doing. :P

#import "NSObject.h"
#include <stdio.h>

@interface Test : NSObject
@property (getter=myStuff) int stuff;
@end

@implementation Test
-(int)myStuff { return 42; }
-(void)setStuff:(int)value { /* don't care */ }
@end


int main() {
    @autoreleasepool {
        Test* test = [[Test alloc] init];

        /* All these work... */
        printf("test.stuff == %d\n", test.stuff);
        printf("[test myStuff] == %d\n", [test myStuff]);
        printf("test.myStuff == %d\n", test.myStuff);

        /* but here, there's an exception */
        printf("[test stuff] == %d\n", [test stuff]);

        return 0;
    }
}

When i compile this (using clang in Linux), there are two warnings about the oddness of a missing -(int)stuff. And the output looks like

chao@chao-VirtualBox:~/code/objc$ ./a.out
test.stuff == 42
[test myStuff] == 42
test.myStuff == 42
: Uncaught exception NSInvalidArgumentException, reason: -[Test stuff]: unrecognized selector sent to instance 0x2367f38
chao@chao-VirtualBox:~/code/objc$ 

So, umm, yeah. Disregard half of the stuff below. :P


self.working is just syntactic sugar for [self working] (or [self setWorking:value] if you're assigning to it). Either one will do the same thing: return the value of [self isWorking], because that's the getter you defined.

If you want to avoid the getter, try _working or self->_working (or whatever you named the ivar). Otherwise, self.working, [self working], and [self isWorking] (and even self.isWorking if you're feeling brave) should all give you the same result.

Upvotes: 3

Related Questions