首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C Block代碼塊回調機制深度解析

     編輯:關於C語言

Objective-C Block代碼塊回調機制深度解析

一、Block機制概述

iOS 4+引入,將代碼片段封裝為對象,可作為參數傳遞、存儲、延遲調用。本質是匿名函數,捕獲上下文變量。

二、Block變量類型

類型由返回值類型與參數列表決定:

// 封裝:^ 參數列表 { 代碼體 }
VoidBlock logBlock = ^{ NSLog(@"Hello Block"); };
IntBlock addBlock = ^(int a, int b) { return a + b; };

// 調用
logBlock();           // 輸出 "Hello Block"
int sum = addBlock(3, 5); // sum = 8

// Block變量可賦值給同類型變量
IntBlock anotherAdd = addBlock;
NSLog(@"%d", anotherAdd(10, 20)); // 30

四、Block對變量作用域的捕獲機制

默認行為:按值捕獲(複製)局部變量,Block內使用的是副本。

__block int modifier = 10; // 使用__block修飾

VoidBlock block = ^{
    NSLog(@"modifier = %d", modifier); // 捕獲副本,值為10
};
modifier = 20; // 修改原變量
block(); // 仍輸出10 —— 副本未變

__block修飾符:引用捕獲

__block int modifier = 10;

VoidBlock block = ^{
    NSLog(@"modifier = %d", modifier); // 共享同一內存
};
modifier = 20;
block(); // 輸出20 —— 讀取最新值

// Block內也可修改
__block int counter = 0;
VoidBlock increment = ^{ counter++; };
increment(); // counter = 1

應用場景:Block需修改外部局部變量、或需讀取最新值時使用__block。

五、Block回調接口設計

優於Target-Action/Delegate:無需分離target與action,代碼內聯定義,上下文自動捕獲,每個回調獨立。

開關組件Block回調版

typedef enum : NSUInteger {
    SwitchStateOff, SwitchStateOn
} SwitchState;

typedef void (^SwitchBlock)(SwitchState state);

@interface SwitchBlockBased : NSObject
@property (nonatomic, assign, readonly) SwitchState currentState;
@property (nonatomic, copy) SwitchBlock changeStateHandler; // copy修飾Block
@end

// 使用者:Room類
@interface Room : NSObject
@property (strong, nonatomic) Light *light;
@property (strong, nonatomic) SwitchBlockBased *switch;
@end

@implementation Room
- (instancetype)init {
    self = [super init];
    if (self) {
        self.light = [[Light alloc] init];
        self.switch = [[SwitchBlockBased alloc] init];
        
        // 關鍵:__weak __block 打破循環引用
        __weak __block Room *weakSelf = self;
        self.switch.changeStateHandler = ^(SwitchState state) {
            if (state == SwitchStateOff)
                [weakSelf.light turnOff];
            else
                [weakSelf.light turnOn];
        };
    }
    return self;
}
@end

六、關鍵最佳實踐

  1. Block屬性用copy:將棧上Block複製到堆上,延長生命週期
  2. 循環引用防範:__weak __block typeof(self) weakSelf = self; 在Block內使用weakSelf
  3. 參數設計:回調Block參數攜帶足夠上下文信息(如狀態枚舉、錯誤對象、結果數據)
  4. 命名規範:Handler/Callback/Completion作為後綴,如completionHandler

七、三種回調模式對比

模式Target-ActionDelegate委托Block
綁定方式target + selectordelegate對象 + 協議方法Block變量
參數靈活性固定(sender)協議定義,可攜帶豐富參數完全自定義
多實例隔離困難需在方法內判斷sender天然隔離,每個Block獨立
代碼組織分散分散內聯,上下文清晰
適用場景簡單控件複雜組件、多回調事件異步操作、動畫、網絡請求、簡單回調
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved