兩種寫法在編譯後的機器碼層面**完全等價**,無任何效能差異:
// 寫法一:直接賦值
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
// 寫法二:臨時變量中轉
UITableView *tbView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView = tbView;
retain/release 序列。self.tableView = ... 編譯為 [self setTableView:...],內部執行 retain 新值、release 舊值、賦值。中轉變量 tbView 只是多了一個棧上指針,優化後會被消除。| 場景 | 直接賦值 | 臨時變量 |
|---|---|---|
| 斷點調試 | 無法單獨檢查新建對象 | 可在 tbView 處打斷點檢查屬性 |
| 多行配置 | 需用鏈式語法或分多句 | 可集中配置後再賦值,可讀性更好 |
| 錯誤處理 | 初始化失敗直接賦值 nil | 可先判斷 if (tbView) 再賦值 |
| KVO 觸發時機 | 同一次 setter 調用 | 同一次 setter 調用 |
self.tableView = UITableView(frame: view.bounds, style: .plain)
self.tableView.delegate = self
self.tableView.dataSource = self
let tableView = UITableView(frame: view.bounds, style: .plain).configure {
$0.delegate = self
$0.dataSource = self
$0.register(Cell.self, forCellReuseIdentifier: "Cell")
$0.estimatedRowHeight = 44
$0.separatorStyle = .none
}
self.tableView = tableView
配合擴展:
extension NSObject {
@discardableResult
func configure(_ block: (Self) -> Void) -> Self {
block(self)
return self
}
}
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
self.tableView = tableView; // 統一在最後賦值,便於調試、重構
誤區:「臨時變量會導致多一次 retain/release,效能較差」
事實:編譯器優化後零開銷。即使不優化,多一次棧上指針賦值成本可忽略不計(納秒級)。
誤區:「直接賦值無法設置屬性,必須用臨時變量」
事實:Swift 支援鏈式屬性設置;OC 可用點語法連續設置
self.tableView.delegate = self; self.tableView.dataSource = self;。
**本質上無任何區別**,選擇哪種純粹是**代碼風格與可讀性**的考量。現代 Swift 推薦「建立常量 → 鏈式/閉包配置 → 賦值屬性」的流暢風格;OC 時代習慣「臨時變量配置完畢再賦值」。關鍵原則:**保持團隊風格一致,優先可讀性**。