兩種寫法對比
// 方式一:alloc/init (手動釋放時代 / 非 ARC)
NSArray *arr1 = [[NSArray alloc] initWithObjects:@"Liza", @"Lipi", @"Rose", nil];
// 需手動 [arr1 release] (MRC)
// ARC 下自動管理,相當於強引用持有
// 方式二:類方法 (便利構造器)
NSArray *arr2 = [NSArray arrayWithObjects:@"Liza", @"Lipi", @"Rose", nil];
// 返回 autoreleased 對象 (MRC 需 autorelease pool)
// ARC 下同樣自動管理
歷史背景:MRC (手動引用計數) 時代
| 特性 | alloc/init | arrayWithObjects |
| 擁有權 | 調用者擁有 (retainCount=1) | 不擁有 (autoreleased) |
| 釋放責任 | 調用者必須 release | 自動釋放池稍後 release |
| 生命周期 | 直到手動 release | 當前 autorelease pool 排空時 (通常 RunLoop 結束) |
ARC (自動引用計數) 時代:本質無差異
- 編譯器自動插入
retain/release/autorelease
- 兩種寫法生成的機器碼幾乎相同
- arr1 和 arr2 都是強引用持有,生命周期由作用域決定
現代最佳實踐:字面量語法 (Objective-C 現代語法)
// 推薦:簡潔、可讀、編譯期檢查
NSArray *arr = @[@"Liza", @"Lipi", @"Rose"];
// 可變陣列
NSMutableArray *mArr = [@[@"Liza", @"Lipi", @"Rose"] mutableCopy];
性能微觀差異 (可忽略)
alloc/init:直接分配、初始化
arrayWithObjects:內部調用 alloc/init 後 autorelease,多一次 autorelease pool 操作 (極微小)
- 字面量
@[]:編譯器優化,可能直接生成靜態常數陣列 (編譯期常數情況)
總結建議
- 統一使用字面量
@[]:現代、安全、簡潔
- 避免
arrayWithObjects: 可變參數陷阱:必須以 nil 結尾,漏寫導致崩潰
- 需要可變陣列時:
[@[...] mutableCopy] 或 [NSMutableArray arrayWithArray:@[...]]
- 理解歷史差異僅為維護舊代碼:新代碼無需關心 MRC 規則