关于C#:iOS:使用self和下划线(_)和变量

iOS: Usage of self and underscore(_) with variable

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?

在如下所示合成变量名之后,我很困惑地使用self或下划线:

1
2
3
4
5
In .h file:
@property(nonatomic, strong) NSMutableArray *users;

In .m file:
@synthesize users = _users;

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

_users是用户的一个实例变量,通常在访问用户变量时使用。如果我使用_users来更改它的值,那么它不会激发kvo委托,而kvo委托不会通知观察用户值更改的类。

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

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

有人能告诉我在使用_usersself.users时,我是否理解错误或遗漏了什么吗?


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

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

下面是一个很好的演示:

1
2
3
- (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
}

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

这也是关于吸气剂的问题。

关于基本内存管理(在MRRARC的情况下):如果没有更强大的指针来保持对象的活动状态,无论您如何释放对象的指针,IOS都会释放对象。


我认为这有助于考虑编译器是如何实现属性的。

当你写self.users = array;时,编译器会把它翻译成[self setUsers:array];。当你写array = self.users;时,编译器会把它翻译成array = [self users];

@synthesize在对象中添加了一个ivar(除非您自己添加),并为您实现了-users-setUsers:访问方法(除非您提供自己的访问方法)。

如果您使用的是ARC,那么-setUsers:将类似于:

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

如果您使用的是MRC(即未启用ARC),那么-setUsers:将类似于*:

1
2
3
4
5
6
- (void)setUsers:(NSArray *)users
{
    [users retain];
    [_users release];
    _users = users;
}

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


是的,那是非常正确的。几个要点:

iOS不会因为使用点符号而自动释放对象。当财产被宣布为copyretainstrong时,它释放一个对象。例如,如果您使用的是非ARC代码,并且该属性声明为assign,则它不会释放该对象。

使用最新版本的开发人员工具链(Xcode4.4+),您不再需要手动合成属性——它们是自动合成的(带有前导下划线)。