点语法与getter =的方法语法

Pau*_*l.s 12 objective-c

我不确定这个问题有多少用处,但对我来说似乎很有意思......

我认为使用property/synthesize语句等同于我创建getter/setter.因此

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

// .m
@synthesize on = _on;

// In my mind synthesizes the following methods

// - (BOOL)on;
// - (void)setOn:(BOOL)on;
Run Code Online (Sandbox Code Playgroud)

但是,如果我将声明更改为以下内容:

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

@synthesize on = _on;

// In my mind synthesizes the following

// - (BOOL)isOn;
// - (void)setOn:(BOOL)on;
Run Code Online (Sandbox Code Playgroud)

然后给出上面的内容我覆盖了getter,所以我知道它何时被调用:

- (BOOL)isOn;
{
    NSLog(@"I was called");
    return _on;
}
Run Code Online (Sandbox Code Playgroud)

现在在实例(myClass)上调用以下内容会导致:

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
Run Code Online (Sandbox Code Playgroud)

我一直认为,如果我在这个意义上使用属性,那么在表单中使用带有点语法的getter/setter是完全有效的

myClass.isOn;
myClass.on = on;
Run Code Online (Sandbox Code Playgroud)

从另一个问题建议,当使用点语法时,我应该使用如下属性名称:

myClass.on   // Correct
myClass.isOn // Incorrect
Run Code Online (Sandbox Code Playgroud)

虽然这可行但似乎略显不合逻辑,因为我知道它没有底层方法- (BOOL)on而是映射到它- (BOOL)isOn

我的问题是(使用后一个例子)

  • 这是一个错误还是应该myClass.on默默地改变为调用- (BOOL)isOn
  • 从语义上讲,我正在访问状态而不是调用行为,所以我目前使用的点语法是否正确?(例如myClass.isOn)

更新

虽然没有人明确地说过它我已经推断使用.isOn是不好的形式,因为无论在引擎盖下调用相同的方法,语义上isOn是在问一个问题,这是更多的行为而不是状态.

然而,我仍然不清楚"魔术"接线在哪里转动呼叫myClass.on进入[myClass isOn]


更新2

在查看了文档后,我在" 声明属性"中找到了此部分.使用以下代码,我可以检查类的属性:

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\n", property_getName(property), property_getAttributes(property));
}

//=> 2012-02-10 07:10:28.333 Untitled[934:707] Name: on, attributes: Tc,GisOn,V_on
Run Code Online (Sandbox Code Playgroud)

所以我们有以下属性:

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

在运行时可以获得所有这些信息,这有点问题是这个查找是在运行时还是编译时完成的,就像一些答案所示?

CRD*_*CRD 4

然而我仍然不清楚“神奇”的接线在哪里将对 myClass.on 的调用变成 [myClass isOn]

在获取上下文中编译 obj.name 时,逻辑肯定如下所示:

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
}
Run Code Online (Sandbox Code Playgroud)

语言/执行环境还有其他方法可以处理自定义 getter 名称,但考虑到 Obj-C 将声明放在标头中(这是公共的),上面可以很好地猜测在编译时执行自定义 getter 逻辑的位置呼叫站点。