可能重复:
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;
}
在使用_users
或self.users
时,有人可以告诉我是否有任何我理解错误或遗失的内容?
答案 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
}
这也是吸气剂的重点。
关于基本内存管理(如果是MRR
或ARC
):如果没有更强的指针使其保持活动状态,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不会因为您使用点表示法而自动释放对象。当属性声明为copy
或retain
(或ARC中的strong
)时,它会释放对象。例如,如果您使用非ARC代码并且该属性声明为assign
,则它不会释放该对象。
使用最新版本的开发人员工具链(Xcode 4.4+),您不再需要手动合成属性 - 它们会自动合成(使用前导下划线)。