__block ViewController *aa = self;
bb = ^{
NSLog(@"%d", aa->age); // EXC_BAD_ACCESS
};
Block_copy(bb); // 錯誤:未賦值給變量
bb 是棧上的 Block,調用 Block_copy(bb) 返回堆上的副本,但未賦值回 bb,後續調用仍用棧副本(已失效)。__block 修飾的變量在 Block 複製時會一起複製到堆,但 aa 指向的 self 若已釋放則野指針。// 1. Block 作為實例變量持有
@property (copy) void (^bb)(void);
// 2. 複製並賦值
bb = Block_copy(^{
NSLog(@"%d", self.age); // 直接捕獲 self,ARC 環境下自動 retain
});
// 3. 非 ARC 環境需手動 retain self
__block ViewController *weakSelf = self;
bb = Block_copy(^{
[weakSelf retain]; // 手動管理生命周期
NSLog(@"%d", weakSelf->age);
[weakSelf release];
});
// 4. 使用時調用
bb();
__weak typeof(self) weakSelf = self;
self.bb = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"%d", strongSelf.age);
}
};
避免循環引用,安全訪問實例變量。