【问题标题】:Calling properties' getter method with dot notation使用点表示法调用属性的 getter 方法
【发布时间】:2014-01-02 10:37:35
【问题描述】:

我在使用 Objective-C 属性时遇到了一些困难。我展示一段代码只是为了解释我的疑问:

啊.h

@interface A : NSObject
@property (nonatomic,getter = isChosen) BOOL chosen;
@end

ma​​in.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 时才会注意到这一点 property 声明中的 em> 名称,否则 NSLog 2 和 4 相同。

【问题讨论】:

    标签: objective-c properties getter accessor


    【解决方案1】:

    点语法是访问器方法调用的简洁替代方案
    除了进行显式访问器方法调用外,Objective-C 还提供了另一种点语法来访问对象的属性。

    点语法允许您访问如下属性:

    NSString *firstName = somePerson.firstName;
    somePerson.firstName = @"Johnny";
    

    点语法纯粹是对访问器方法调用的方便包装。当您使用点语法时,仍然可以使用上面提到的 getter 和 setter 方法访问或更改属性:

    使用 somePerson.firstName 获取值与使用 [somePerson firstName] 相同 使用 somePerson.firstName = @"Johnny" 设置值与使用 [somePerson setFirstName:@"Johnny"] 相同 这意味着通过点语法访问属性也由属性属性控制。如果一个属性被标记为只读,如果你尝试使用点语法设置它,你会得到一个编译器错误。

    Have a look at this

    从变量中读取,点表示法和直接读取是相同的。在您的情况下,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 的快捷方式。您也可以使用点作为吸气剂。没有问题,这也不是不好的做法。来自Obj-C 2.0 programming guide,“您可以使用点语法调用访问器方法,使用与访问结构元素相同的模式。点语法纯粹是“语法糖””。请注意,它说的是访问器方法,而不仅仅是设置器。

    编辑 2
    在寻找您的答案时,我发现了这个..想与您分享..

    如果你有一个成员变量,并且你的这个变量的 getter 被称为 isOn 那么 .on 和 .isOn 是两种非常不同的东西。通过使用 getter(也可能是 setter),您将遵守“信息隐藏”的承诺,而通过直接访问成员变量则不会。 Cocoa 不会强制执行这些事情,因为它依赖于约定。由您决定哪种方式适合您。考虑到约定,您将不得不坚持使用 setter 和 getter - 不管您给它们起什么名字。

    “总的来说,我认为这是对语言的一个相当愚蠢的补充,因为我们已经有了发送消息的语法。” -Aaron Hillegass(Mac OSX 的 Cocoa 编程,第 3 版)

    希望这个对你有帮助……:)

    【讨论】:

    • 我认为您没有明白这一点,因为我已经理解了您在帖子中所说的内容(从我的帖子中应该很清楚)。我觉得很奇怪的是myClass.isChosen 调用,因为它既不是myClass.chosen(其中chosen属性)也不是[myClass isChosen](其中isChosengetter 方法用于chosenproperty)。我是说将点表示法与 getter 而不是属性一起使用有点奇怪。
    • 感谢@achievelimitless 在您的回答中投入了这么多时间!
    • 这个答案的最后一点是错误的。 .on.isOn 都会调用 getter。如果您在头文件中声明变量,然后使用->on 语法,您将直接获取变量,这是一个非常糟糕的主意。不过,两种点语法都可以。
    • hi @jake.. 你可能不赞成在代码中使用 -> ,但我已经看到一些使用这些的苹果代码。所以,这可能不是一个坏主意..如果我错了,请告诉我..:)
    猜你喜欢
    • 2013-01-30
    • 2018-07-14
    • 2020-09-17
    • 2021-05-25
    • 1970-01-01
    • 2012-01-27
    • 2012-10-24
    • 2013-10-19
    • 2018-09-05
    相关资源
    最近更新 更多