在init方法中使用setter进行赋值(objective-c)

时间:2012-08-17 17:32:45

标签: objective-c ios5

我知道在类的方法中赋值的正确约定是不使用setter版本。

鉴于你有一个像这样的init方法:

// Class header 
@property (nonatomic, weak) id <DelegateType> delegate;
@property (nonatomic, strong) NSString *stringData;

@synthesize delegate = _delegate;
@synthesize stringData = _stringData;

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    // initialization happens here
}

预ARC,您可以通过以下方式确保正确的保留政策:

stringData = [aString retain];
self.delegate = aDelegate;

使用ARC,如何进行分配并确保ivars不会过早发布?

因为你不知道在设置者覆盖的情况下可能在幕后发生什么样的工作,我的印象是你做不到:

self.stringData = aString

正确的初始化模式是什么?

3 个答案:

答案 0 :(得分:1)

由于您正在使用属性

// Class header 
@property (nonatomic, weak) id <DelegateType> delegate;
@property (nonatomic, strong) NSString *stringData;

@synthesize delegate = _delegate;
@synthesize stringData = _stringData;

因此,根据ARC,对象的工作方式与分配相似。但是“强”基本上不像保留那样工作,因为保留只增加引用计数,而对于ARC,强类型的对象肯定存在,直到该类的实例存在。

所以在init方法

应该是

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
// now _stringData and _delegate are getter instance of property variables. so either you can use self.stringData and self.delegate or _stringData and _delegate.
    _stringData = aString;
    _delegate = aDelegate;
}

答案 1 :(得分:0)

你可以,事实上,你应该(在大多数情况下)使用访问器来访问你的ivars,即使你在ARC的实现中也是如此。它比你想象的更聪明。没有“太早”发布的伊娃。

答案 2 :(得分:0)

只需分配到ivar。 ARC将根据变量的内存管理策略(__strong__weak__unsafe_unretained)来处理保留和释放。这就是ARC的观点。所以你的代码示例是:

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    stringData = aString;
    delegate = aDelegate;
}

但是,除此之外,您应该复制该字符串而不是保留。因此,您将setter声明为@property (nonatomic, copy) NSString *stringData;,init方法的实现将是:

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    stringData = [aString copy];
    delegate = aDelegate;
}