10

可能重复:
可可objective-c 类中变量前面的下划线如何工作?

在如下合成变量名后,我对使用 self 或带下划线的变量名感到非常困惑:

In .h file:
@property(nonatomic, strong) NSMutableArray *users;

In .m file:
@synthesize users = _users;

根据我在使用时的理解self.users,操作系统会确保在 set 方法中释放之前分配的内存,所以我们不需要明确注意。

_users是用户的实例变量,应该在访问用户变量时正常使用。如果我_users用来更改它的值,那么它不会触发 KVO 委托,它不会通知观察用户值变化的类。

此外,self.users允许在方法名称中区分虚拟变量,如下所示,

- (void)assignUsers:(NSMutableArray*)users {
      self.users = users;
}

_users有人可以告诉我在使用or时是否有任何我理解错误或遗漏的地方self.users

4

3 回答 3

31

当您使用 时self.users,您可以通过 setter 或 getter 访问该属性。

当您使用 时_users,您可以直接跳过 setter 或 getter 访问属性。


这是一个很好的演示:

- (void)setUsers:(id)users {
    self.users = users; // WRONG : it causes infinite loop (and crash), because inside the setter you are trying to reach the property via setter
}

- (void)setUsers:(id)users {
    _users = users; // GOOD : set your property correctly
}

这也是 getter 的重点。


关于基本内存管理(在MRRor的情况下ARC):如果没有更多的强指针使其保持活动状态,iOS 将释放对象,无论您如何释放对象的指针。

于 2012-08-29T10:27:59.887 回答
8

我认为考虑编译器如何(或可能)实现属性会有所帮助。

当您编写self.users = array;编译器时,编译器将其翻译为[self setUsers:array]; 当您编写时array = self.users;,编译器将其翻译为array = [self users];

@synthesize将 ivar 添加到您的对象(除非您自己添加),并为您实现-users-setUsers:访问器方法(除非您提供自己的

如果您使用ARC-setUsers:将如下所示:

- (void)setUsers:(NSArray *)users
{
    _users = users; // ARC takes care of retaining and release the _users ivar
}

如果您使用的是MRC(即ARC未启用),-setUsers:将如下所示*:

- (void)setUsers:(NSArray *)users
{
    [users retain];
    [_users release];
    _users = users;
}

* -请注意,这是一个简化的非原子实现-setUsers:

于 2012-08-29T10:50:21.163 回答
2

是的,这非常正确。几个小点:

iOS 不会因为您使用点符号而自动释放对象。当属性被声明为copyor retain(或strong在 ARC 中)时,它会释放一个对象。例如,如果您使用的是非 ARC 代码并且该属性被声明为assign,则它不会释放该对象。

使用最新版本的开发工具链(Xcode 4.4+),您不再需要手动合成属性 - 它们会自动合成(带有前导下划线)。

于 2012-08-29T11:49:18.093 回答