self.name和_name之间的区别使用现代Objective-C

时间:2014-05-29 19:48:23

标签: objective-c properties instance-variables accessor

说这是在我的头文件中:

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (weak) IBOutlet NSSlider *slider;
- (void)doSomething;

@end

......这是* m:

@implementation AppDelegate

- (void) doSomething {[self.slider setFloatValue:0];}

@end

我是Xcode和Objective C的新手,我想使用和理解Apple在其文档中提供的现代“工具”,即ARC,或者更具体地说是跳过{{1}的能力}。

如果我理解正确,@synthesize会为我做一些事情,包括:

  • 创建名为@property (weak) IBOutlet NSSlider *slider;;
  • 的实例变量
  • 创建名为_slider;
  • 的getter
  • 创建名为slider
  • 的setter

到目前为止我一直在做C ++,所以我看到实例变量等同于我所调用的(正确的,我希望)我的C ++类的成员,我偶然致电setSlider

我理解封装的全部意义在于,如果您不在给定的类之外,则必须使用访问器来访问这些变量;他们是私人的,所以即使你尝试过,也无法通过_member访问它们。

但是,当我正在写我班级的* .m文件时,_member意味着什么。回到我的例子,我认为_memberself.slider是等价的。后者自然首先考虑到,因为它节省了一些角色。

我的问题是:两个绝对等价?

我知道这看起来与this question相似,但这里有几个原因让我问自己:

  • 我不使用_slider,所以我真的不是那个创建@synthesize的人,我想知道这是否有所作为(我相信这是ObjC最近的改进,并且大多数答案仍然提到_slider);
  • 似乎平均而言,大多数对话都以“所以,只使用@synthesize”结束,但我不知道这是否只是一个更重要的推荐,约定(具有影响力)比如表演);
  • 同样,有人说你应该只在self.name及其朋友等方法中使用_name;但是我不会写这些感谢ARC,所以这是否意味着我从不使用dealloc?如果是这样,为什么

我希望这可以证明这篇文章是正确的,如果我错过了一个预先存在的答案,我道歉。在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

self.name =编译为[self setName:]这与直接设置变量非常不同。

使用默认设置器的主要原因之一是处理键值观察,通常称为KVO。使用setter会通知观察者更改,直接设置_name不会。

这并不是说你不能用willChangeValueForKey:didChangeValueForKey:来解雇你自己的事件,但默认的实现会为你处理。因此,当您在课堂外访问它们时,您必须使用属性get / set,但在您的类设置中,直接变量会丢失一些通知。我确信还有其他的不同之处,这是我想到的第一个。

直接使用变量确实有它的用例,例如自定义属性设置器。我认为主要的用处是点语法是一个隐藏函数调用get / set。

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html

答案 1 :(得分:0)

在基本情况下,如果您使用预先制作的访问者,您可能可以互换地使用班级中的_sliderself.slider。它们在编译方式上并不相同,但功能可以说是等效的。

当您开始覆盖这些访问者时,更大的问题就会发挥作用。当那些访问者做的不仅仅是&#34;获得&#34;或&#34;设置&#34;一个变量,比如访问某个排序依赖变量,直接访问实例变量就会绕过访问者提供的功能。在这些情况下,我不认为可以说两者完全相同。