我在使用 Objective-C属性时遇到了一些困难。我正在展示一段代码来解释我的疑问:
A.H
@interface A : NSObject
@property (nonatomic,getter = isChosen) BOOL chosen;
@end
的main.m
A *myClass = [[A alloc]init];
myClass.chosen = YES;
NSLog(@"1. myClass.chosen = %hhd", myClass.chosen);
myClass.chosen = NO;
NSLog(@"2. myClass.chosen = %hhd", myClass.chosen);
NSLog(@"3. myClass.chosen = %hhd", [myClass isChosen]);
NSLog(@"4. myClass.chosen = %hhd", myClass.isChosen);
输出
1. myClass.chosen = 1
2. myClass.chosen = 0
3. myClass.chosen = 0
4. myClass.chosen = 0
除了最后一行代码之外,一切都很清楚,我用myClass.isChosen
获取所选属性的值:我理解点语法myClass.chosen
,因为编译器在消息符号语法[myClass isChosen]
中转换它,但我真的不明白为什么myClass.isChosen
有效,或者更好,我认为编译器再次以消息符号转换它,但似乎对我来说有点奇怪。
我想知道用点符号语法调用getter方法是否被认为是一种好习惯,如果它对我来说似乎很奇怪..显然只有当你改变 getter时才注意到这一点属性声明中的em> name,否则 NSLog 2和4 是相同的。
答案 0 :(得分:4)
点语法是访问者方法调用的简明替代方案
除了进行显式访问器方法调用之外,Objective-C还提供了一种替代点语法来访问对象的属性。
Dot语法允许您访问以下属性:
NSString *firstName = somePerson.firstName;
somePerson.firstName = @"Johnny";
Dot语法纯粹是一个围绕访问器方法调用的方便包装器。使用点语法时,仍然可以使用上面提到的getter和setter方法访问或更改该属性:
使用somePerson.firstName获取值与使用[somePerson firstName]相同 使用somePerson.firstName = @“Johnny”设置值与使用[somePerson setFirstName:@“Johnny”]相同 这意味着通过点语法进行的属性访问也由属性属性控制。如果属性被标记为只读,如果您尝试使用点语法设置它,则会出现编译器错误。
从变量读取,点符号&直读是一样的。在您的情况下,myClass.chosen
与[myClass isChosen]
相同。在这里你刚给你的getter命名了一个名字。因此,您不是致电[myClass chosen]
,而是致电[myClass isChosen]
。在分配变量时,差异会出现在图片中。就是这样,
[self setVar:foo]
与self.var=foo
相同
但,
self->var= foo;
与[self setVar:foo]
不同
直接赋值给变量不会泄漏内存,而self.var
调用访问器方法&因此增加保留计数。如果需要更多信息,请告诉我
修改
对不起,我之前没有理解你 点(。)不仅是setter的快捷方式,也是getter的快捷方式。你也可以使用dot作为getter。没有问题,这也不是坏习惯。从Obj-C 2.0 programming guide开始,“您可以使用点语法来使用与访问结构元素相同的模式来调用访问器方法。点语法纯粹是”语法糖“。注意,它是关于访问器方法,而不仅是setter。
编辑2
在寻找你的答案时,我发现了这个......想与你分享..
当你有一个成员变量,并且你的这个变量的getter被称为isOn然后.on和.isOn是两种非常不同的东西。通过使用getter(也可能是setter),您将遵循“信息隐藏”承诺,而通过使用直接访问成员变量,您将不会。 Cocoa不会强制执行这些事情,因为它依赖于约定。由您决定哪种方式适合您。考虑到惯例,你必须坚持使用setter和getter - 不管你给他们什么名字。
“总的来说,我认为这是对语言的一种相当愚蠢的补充,因为我们已经有了发送消息的语法。” -Aaron Hillegass(Mac OSX的可可编程,第3版)
希望这个能帮助你...... :)