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

Objective-C 基礎筆記(六):Block 語法與應用詳解

     編輯:關於C語言

Objective-C Block 完全指南

Block(塊)是蘋果為 C 語言增加的閉包特性,封裝一段可執行代碼,支持參數、返回值、捕獲外部變量。廣泛用於多線程(GCD)、異步回調、集合遍歷/排序、動畫轉場等場景。

基本語法

// 定義一個 Block 類型別名
typedef int (^MySumBlock)(int, int);

// 定義並賦值 Block 變量
MySumBlock sumBlock = ^(int a, int b) {
    return a + b;
};

// 調用
int result = sumBlock(3, 5); // 8

捕獲外部變量:__block 修飾符

默認情況下,Block 內訪問外部局部變量為只讀(值捕獲)。若需在 Block 內修改外部變量,必須加 __block。

void testBlockVariableCapture() {
    int readOnly = 10;
    __block int writable = 20;

    void (^printer)(void) = ^{
        NSLog(@"readOnly: %d", readOnly); // OK
        // readOnly = 15; // 編譯錯誤:只讀
        
        writable = 30; // OK:__block 允許修改
        NSLog(@"writable: %d", writable);
    };
    
    printer();
    NSLog(@"After block, writable = %d", writable); // 30
}

實戰案例:按鈕點擊回調

用 Block 替代傳統 Target-Action 或 Delegate,代碼更聚合。

// Button.h
typedef void (^ButtonClickBlock)(id sender);

@interface Button : NSObject
@property (nonatomic, copy) ButtonClickBlock clickHandler; // 必須用 copy
- (void)simulateClick;
@end

// Button.m
@implementation Button
- (void)simulateClick {
    if (self.clickHandler) {
        self.clickHandler(self); // 回調
    }
}
@end

// 使用
Button *btn = [Button new];
btn.clickHandler = ^(id sender) {
    NSLog(@"按鈕 %@ 被點擊", sender);
};
[btn simulateClick];

關鍵點:Block 屬性必須用 copy,因為 Block 初始在棧上,copy 會將其複製到堆上,延長生命周期。

Block vs 函數指針

特性Block函數指針
語法^(參數){ 體 }返回類型 (*名)(參數)
捕獲上下文✅ 自動捕獲外部變量❌ 無法直接捕獲,需傳 void* 上下文
內聯優化✅ 編譯器可內聯❌ 難以內聯
內存管理需 copy/release (MRC) 或 ARC 自動管理僅代碼段地址,無生命周期問題

常見陷阱:循環引用

Block 捕獲 self 且 self 持有 Block 會導致循環引用。解決:在 Block 內使用 __weak 弱引用。

__weak typeof(self) weakSelf = self;
self.completionBlock = ^{
    [weakSelf doSomething]; // 不持有 self
};

總結

Block 是現代 Objective-C 開發的核心工具。掌握 __block、copy、循環引用處理,能寫出更簡潔、安全的異步代碼。

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