對象alloc後引用計數為1,賦值給retain屬性預期計數+1變為2,但實際觀察計數仍為1。代碼片段:
@property (nonatomic, retain) TestJob *myObject;
// 使用時
_myObject = [testJob retain]; // 未走setter
@property (retain)的retain語義僅在setter方法內生效。直接賦值給實例變量_myObject繞過了setter,因此不會觸發retain操作。
| 方式 | 代碼 | 計數變化 |
|---|---|---|
| ❌ 錯誤 | _myObject = [obj retain]; | 不觸發setter,屬性語義失效 |
| ✅ 正確 | self.myObject = obj; | 自動調用setter,retain生效 |
| ✅ 手動 | [self setMyObject:obj]; | 顯式調用setter,效果相同 |
self.property = ...或[self setProperty:...]賦值_ivar需手動管理引用計數可重寫setter加日誌驗證:
- (void)setMyObject:(TestJob *)obj {
NSLog(@"setter called, retainCount before: %lu", [obj retainCount]);
_myObject = obj;
NSLog(@"retainCount after: %lu", [obj retainCount]);
}
理解「屬性語義=setter行為」是掌握OC內存管理的關鍵。