2014-06-09 36 views
0

我對這段代碼有些疑惑:Self.target =等同於[self setTarget]對於合成屬性嗎?

@interface Foo { 
    id target_; 
} 
@property (nonatomic, readwrite, retain) id target; 

@implementation Foo 

@synthesize target = target_; 

-(id)initWithTarget:(id)t { 
    if((self=[super init])) { 
     self.target = t; 
    } 
    return self; 
} 

-(void) dealloc { 
    [target release]; 
    [super dealloc]; 
} 

@end 

問題:

  • self.target = t完全等同於[self setTarget:t]
    • 如果是,target = t怎麼辦?
    • 如果是,target保留,對不對?
  • 這將是完美的罰款打電話self.target = nildealloc方法,對嗎?因爲二傳手會釋放target

回答

1

self.target = t完全等價於[self setTarget:t]?

是的。 self.target =幾乎相當於setTarget:。在某些情況下,它們都將編譯爲完全相同的二進制文件,在其他情況下,self.target =將會有細微的差異,這會使其執行速度快於setTarget:,但行爲方式相同。

如果是,那麼target = t呢?

不,這是不一樣的。你應該避免做target_ = - 這種方法直接訪問C指針會導致各種問題。有一些邊緣情況需要這樣做,但一般情況下應儘可能避免。

如果是,則保留目標,對嗎?

如果你有ARC 禁用,它的聲明爲retain然後self.target =setTarget:將保留,但target_ =不會保留,並可能在以後導致系統崩潰。如果該財產沒有被宣佈爲retain它將永遠不會保留。

如果您已啓用ARC並且它s declared asthen all three styles of setter will retain the variable. If it's declared as something else (such as弱`)它將不會保留在所有三種情況下。

在dealloc方法中調用self.target = nil會很好,對吧?因爲二傳手會釋放目標。

一般的建議是不使用self.target =setTarget:裏面dealloc。使用[target_ release]; target_ = nil。或者甚至更好,啓用ARC並且不要對dealloc中的目標執行任何操作。

+0

關於最後一個答案,你的意思是'[target_ release]; target_ = nil'吧? – Voldemort

+0

@JustKidding是的,我想這可能是你的問題的錯誤。通過'target = nil'我的意思是通過'target_ = nil'直接設置伊娃。我會編輯我的答案。 –

+0

是否需要'target_ = nil'?我的意思是,dealloc無論如何不是沒有好處? – Voldemort

2
  • 是的。該文檔具有合成屬性如何工作的entire section

    • target = t將無法​​工作,因爲既不是一個實例變量,也稱爲target一個局部變量。

      要設置屬性,您必須必須使用self.target = t[self setTarget:t]

      您仍然可以直接使用target_訪問伊娃,因爲這是它在頭中聲明的方式,但自然這樣做不會觸發訪問器。

    • 只有確保使用屬性設置器進行賦值,並且該屬性被聲明爲retain/strong(默認情況下),纔會保留它。

  • 如果你不使用ARC來管理你的引用(你真的應該),你應該手動釋放的ivars在-dealloc,不設置其屬性爲nil:

    -(void) dealloc { 
        [target_ release]; 
        [super dealloc]; 
    } 
    
1

是的,self.target = t[self setTarget:t]完全等價。

target = t語法不起作用;點語法是必需的。 target_ = t會,但它不會是一回事:沒有方法被調用,KVO觀察者不會被通知,並且值不被保留。

合成二傳手retain屬性會自動釋放先前的值並保留新值。

self.target = nil可以用來代替的dealloc釋放,但我強烈不建議:

  • 它不會爲assign性工作(如果他們的ivars確實需要被釋放某種原因)

  • 不是每一個需要被釋放將會有一個屬性伊娃,所以你的dealloc最終會爲release混合和分配反正

  • 自定義設置器可產生有害的副作用

  • 當你的主要(唯一!)目的是釋放一個對象,你應該把它release消息,而不是做它有這樣做的副作用,一些間接的叫什麼你需要。