Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
689 views
in Technique[技术] by (71.8m points)

objective c - dot syntax vs method syntax with getter=

I'm not sure how much use this question is but it seems interesting to me...

I thought that using property/synthesize statements was equivalent to me creating the getter/setter. Therefore

// .h
@property (nonatomic) BOOL on;

// .m
@synthesize on = _on;

// In my mind synthesizes the following methods

// - (BOOL)on;
// - (void)setOn:(BOOL)on;

However if I change the declarations to the following:

                              v
@property (nonatomic, getter=isOn) BOOL on;

@synthesize on = _on;

// In my mind synthesizes the following

// - (BOOL)isOn;
// - (void)setOn:(BOOL)on;

Then given the above I override the getter so I know when it is called:

- (BOOL)isOn;
{
    NSLog(@"I was called");
    return _on;
}

Now calling the following on an instance (myClass) results in:

NSLog(@"%d", [myClass isOn]);

//=> 2012-02-09 22:18:04.818 Untitled[1569:707] I was called
//=> 2012-02-09 22:18:04.820 Untitled[1569:707] 1
    
NSLog(@"%d", myClass.isOn);
    
//=> 2012-02-09 22:18:24.859 Untitled[1599:707] I was called
//=> 2012-02-09 22:18:24.861 Untitled[1599:707] 1
    
NSLog(@"%d", myClass.on);         // This is the one I didn't expect to work
    
//=> 2012-02-09 22:18:55.568 Untitled[1629:707] I was called
//=> 2012-02-09 22:18:55.570 Untitled[1629:707] 1

I had always assumed that if I was using a property in this sense it was perfectly valid to use the getter/setter with dot syntax in the form

myClass.isOn;
myClass.on = on;

From another question it was suggested that when using dot syntax I should use the property name like this:

myClass.on   // Correct
myClass.isOn // Incorrect

Although this works it seem slightly less logical because I know there is no underlying method - (BOOL)on it is instead mapped to - (BOOL)isOn

My questions are (using the latter example)

  • Is this a bug or should myClass.on really be silently changed to call - (BOOL)isOn
  • Semantically speaking I am accessing state not invoking behaviour so is my current use of dot syntax correct? (e.g. myClass.isOn)

Update

Although no one has explicitly said it I have reasoned that using .isOn is bad form because regardless of the fact that under the hood the same method is called, semantically isOn is asking a question, which is more behaviour rather than state.

However I am still unclear on where the "magic" wiring goes on that turns calls to myClass.on into [myClass isOn]


Update 2

After looking around the docs some more I found this section on Declared Properties. Using the following code I can inspect a class' properties:

id MyClass = objc_getClass("MyClass");
unsigned int outCount, i;

objc_property_t *properties = class_copyPropertyList(MyClass, &outCount);
for (i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    NSLog(@"Name: %s, attributes: %s
", property_getName(property), property_getAttributes(property));
}

//=> 2012-02-10 07:10:28.333 Untitled[934:707] Name: on, attributes: Tc,GisOn,V_on

So we have the following attributes:

  • name = on
  • type = char (Tc)
  • getter = isOn (GisOn)
  • variable = _on (V_on)

With all of this information available at runtime it kind of leaves the question is this lookup done at runtime or compile time like some answers suggest?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

However I am still unclear on where the "magic" wiring goes on that turns calls to myClass.on into [myClass isOn]

The logic surely goes as follows, when compiling an obj.name in a getting context:

if(there is an accessible @property for name in scope)
{
   if(there is a custom getter specified)
      compile "[obj customGetter]"
   else
      compile "[obj name]"
}
else if (there is an an accessible instance method name in scope)
   compile "[obj name]"
else
{
   compile "[obj name]"
   warn obj may not respond to name
}

There are other ways a language/execution environment can handle custom getter names, but given that Obj-C puts the declaration in the header (which is public) the above is a good guess as to where the custom getter logic is performed - when compiling the call site.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...