iOS:使用self和下划线(_)和变量

时间:2012-08-29 09:53:32

标签: ios objective-c memory-management self

  

可能重复:
  How does an underscore in front of a variable in a cocoa objective-c class work?

我在使用自变量或下划线与变量名后非常困惑,如下所示合成它:

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

In .m file:
@synthesize users = _users;

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

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

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

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

在使用_usersself.users时,有人可以告诉我是否有任何我理解错误或遗失的内容?

3 个答案:

答案 0 :(得分: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
}

这也是吸气剂的重点。


关于基本内存管理(如果是MRRARC):如果没有更强的指针使其保持活动状态,iOS将解除对象,无论你如何释放对象的指针。

答案 1 :(得分: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:的简化,非原子实现

答案 2 :(得分:2)

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

iOS不会因为您使用点表示法而自动释放对象。当属性声明为copyretain(或ARC中的strong)时,它会释放对象。例如,如果您使用非ARC代码并且该属性声明为assign,则它不会释放该对象。

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