这是2个代码快照 -
@interface A:NSObject
{
NSMutableArray *a;
}
@property (retain) NSMutableArray *a;
@implementation
@synthesize a;
-(id)init
{
if(self=[super init])
{
a=[[NSMutableArray alloc] init];
}
}
@end
@interface A:NSObject
{
NSMutableArray *_a;
}
@property (retain) NSMutableArray *a;
@implementation
@synthesize a=_a;
-(id)init
{
if(self=[super init])
{
_a=[[NSMutableArray alloc] init];
}
}
@end
现在我需要知道的是,是否在代码实例变量中直接赋值而不是使用访问器并且保留计数是1?或者它们之间存在差异。感谢。
还有一件事,苹果建议不要在init / dealloc中使用访问器,但同时要求不要直接设置iVar。那么在init()中分配ivar值的最佳方法是什么?
答案 0 :(得分:1)
ARC与非ARC
首先,您应该决定是否要使用自动引用计数(ARC)或手动引用计数。看起来你选择了后者 - 这很好,因为你以后总能过渡到ARC。
属性属性/ setter语义
您已将属性a
的setter语义标记为retain
。这将有效;但由于该属性在类接口中公开,因此类用户可以使用它来设置_a
ivar。由于类用户可能不希望您的类A
直接修改它们传递的NSMutableArray
实例,因此最好对可变对象属性使用copy
语义。
init
和dealloc
经常不鼓励在init
和dealloc
中使用声明的属性,因为这样做可能会因KVO而产生副作用。对于部分构造或部分解构的物体,这些副作用可能不适用。
您的问题
这就是我要做的事情:
// assumes Xcode 4.4+ for autosynthesize
@interface A:NSObject
@property (nonatomic,copy) NSMutableArray *a;
@end
@implementation A
- (id)init {
self = [super init];
if( !self ) return nil;
_a = [[NSMutableArray alloc] init];
return self;
}
@end
修改强>
或者,如果没有自动合成:
@interface A:NSObject
@property (nonatomic,copy) NSMutableArray *a;
@end
@implementation A
@synthesize a = _a;
- (id)init {
self = [super init];
if( !self ) return nil;
_a = [[NSMutableArray alloc] init];
return self;
}
@end
答案 1 :(得分:0)
您提到的上述两个代码没有区别。在最新的编译器中,您现在不需要使用property指定实例变量。所以上面的代码现在将是:
@interface A:NSObject
@property (strong) NSMutableArray *a;
@end
@implementation
-(id)init
{
if (self = [super init])
{
_a = [[NSMutableArray alloc] init];
}
return self;
}
@end
在这种情况下,属性“a”具有自动合成,_a是实例变量。基本上_前缀为属性名是实例变量名。
如果在ARC中没有释放。使用self.a访问其他任何地方。
你正确地说Apple建议不要在初始化程序和dealloc中使用属性,因为它们没有初始化。
回答你的问题:“当与属性一起使用时,不同的iVar名称更改保留计数”是指在使用属性时,您不应该担心这一点。它可能在短时间内有不同的保留计数,但对您或代码来说无关紧要。
希望它有所帮助。