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

iOS AFNetworking 異步回調:正確在 Block 外使用網絡請求數據

     編輯:程式設計疑難解答

核心誤區

代碼按**同步思維**寫異步請求:

[manager GET:... success:^(...) {
    arrData = ...; // 異步賦值
} failure:...];
NSLog(@"%@", arrData); // 同步執行,此時 arrData 仍為 nil

Block 內代碼在網絡響應返回時才執行,而外部代碼立即繼續執行,故拿不到數據。

正確模式:回調中驅動 UI 更新

- (void)viewDidLoad {
    [super viewDidLoad];
    // ... 初始化 tableView ...
    
    [manager GET:url parameters:nil progress:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        // 1. 解析數據
        NSError *err = nil;
        XiaHuaModel *xiaHua = [[XiaHuaModel alloc] initWithDictionary:responseObject error:&err];
        self.arrData = [NSMutableArray arrayWithArray:xiaHua.detail]; // 用 self. 觸發 KVO/屬性觀察
        
        // 2. **主線程刷新 UI**(AFNetworking 回調已在主線程,但顯式寫法更安全)
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.xiaoHuaView reloadData]; // 關鍵:通知 tableView 重新查詢 dataSource
        });
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // 錯誤處理:彈窗、重試按鈕、日誌上報
        NSLog(@"Error: %@", error);
    }];
}

關鍵點解析

錯誤做法正確做法理由
期望 Block 外直接用變量在 Block 內賦值並觸發刷新異步非阻塞,時間線不同步
用 __block 修飾局部變量用 屬性 @property (nonatomic, strong) NSMutableArray *arrData;屬性持有強引用,生命周期受控;局部變量易釋放
忽略失敗回調必寫 failure 塊,處理斷網、服務端錯誤用戶體驗與穩健性
在後台線程刷新 UIdispatch_async(dispatch_get_main_queue(), ^{ [tableView reloadData]; })UIKit 非線程安全,必須主線程

進階:封裝為 Promise/Async-Await 風格 (Swift/OC 類別)

// OC 類別方法
+ (void)fetchJokesWithCompletion:(void (^)(NSArray * _Nullable, NSError * _Nullable))completion {
    [manager GET:url parameters:nil success:^(id responseObject) {
        XiaHuaModel *model = [[XiaHuaModel alloc] initWithDictionary:responseObject error:nil];
        completion(model.detail, nil);
    } failure:^(NSError *error) {
        completion(nil, error);
    }];
}

// 調用處
[ViewController fetchJokesWithCompletion:^(NSArray *jokes, NSError *error) {
    if (jokes) {
        self.arrData = [NSMutableArray arrayWithArray:jokes];
        [self.tableView reloadData];
    } else {
        // show error
    }
}];

總結

異步編程核心:不要問「何時能拿到數據」,而要想「拿到數據後做什麼」,並把「做什麼」寫在回調/完成塊裡。

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