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

iOS performSelectorInBackground 傳遞多個參數:封裝字典或使用 Block 回調

     編輯:程式設計綜合問答

問題

performSelectorInBackground:@selector(method:) withObject: **只能傳遞單一對象**,需同時傳遞 UITableViewCell 和 NSString 兩個參數。

方案一:封裝 NSDictionary (經典做法)


- (void)viewDidLoad {
    [super viewDidLoad];
    
    NewsCell *cell = ...; // 獲取 cell
    NSString *imageName = @"image.png";
    
    // 1. 封裝參數字典
    NSDictionary *params = @{
        @"cell": cell,
        @"imageName": imageName
    };
    
    // 2. 後台線程調用包裝方法
    [self performSelectorInBackground:@selector(doSomethingWrapper:) withObject:params];
}

- (void)doSomethingWrapper:(NSDictionary *)params {
    // 3. 解包並調用核心方法
    NewsCell *cell = params[@"cell"];
    NSString *imageName = params[@"imageName"];
    [self doSomething:cell imageName:imageName];
}

- (void)doSomething:(NewsCell *)cell imageName:(NSString *)imageName {
    // 核心邏輯
    NSLog(@"Cell: %@, Image: %@", cell, imageName);
    // 注意:UI 更新必須回主線程
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新 UI
    });
}

方案二:使用 Block (現代、推薦)

performSelectorInBackground 屬於舊式 API,**強烈建議使用 GCD / OperationQueue**:


- (void)viewDidLoad {
    [super viewDidLoad];
    
    NewsCell *cell = ...;
    NSString *imageName = @"image.png";
    
    // 直接在 Block 中捕獲參數,無需封裝
    dispatch_queue_t bgQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
    dispatch_async(bgQueue, ^{
        // 後台執行耗時操作
        NSString *result = [self processCell:cell imageName:imageName];
        
        // 回主線程更新 UI
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateUIWithResult:result];
        });
    });
}

- (NSString *)processCell:(NewsCell *)cell imageName:(NSString *)imageName {
    // 耗時邏輯
    return @"processed";
}

- (void)updateUIWithResult:(NSString *)result {
    // UI 更新
}

方案三:NSInvocation (極少用,複雜)

可封裝多參數調用,但代碼冗長,不推薦日常使用。

關鍵對比

方案優點缺點適用場景
NSDictionary 封裝兼容 performSelector API需手動封裝/解包、類型安全弱維護舊代碼、必須用 performSelector
GCD Block語法簡潔、自動捕獲變量、類型安全、現代標準需理解 Block 內存管理**所有新代碼首選**
OperationQueue支援依賴、優先級、取消、KVO稍繁瑣複雜任務佇列管理

內存管理提醒

  • Block 捕獲 self 會 retain,注意循環引用:__weak typeof(self) weakSelf = self; 在 Block 內使用 weakSelf。
  • performSelectorInBackground 不會自動 retain 參數,若參數在後台執行前被釋放會 Crash。**GCD Block 捕獲會自動 retain**,更安全。

總結

**棄用 performSelectorInBackground,改用 GCD dispatch_async**。Block 自然捕獲多參數,代碼清晰、類型安全、內存管理可控。若必須用舊 API,用 NSDictionary 封裝參數傳遞給包裝方法再解包。

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