首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS Block 捕獲實例變量:__block 與 Block_copy 正確用法

     編輯:程式設計綜合問答

問題代碼

__block ViewController *aa = self;
bb = ^{
    NSLog(@"%d", aa->age); // EXC_BAD_ACCESS
};
Block_copy(bb); // 錯誤:未賦值給變量

原因分析

  1. bb 是棧上的 Block,調用 Block_copy(bb) 返回堆上的副本,但未賦值回 bb,後續調用仍用棧副本(已失效)。
  2. __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();

現代最佳實踐(ARC + weakSelf)

__weak typeof(self) weakSelf = self;
self.bb = ^{
    __strong typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        NSLog(@"%d", strongSelf.age);
    }
};

避免循環引用,安全訪問實例變量。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved