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

iOS 網絡請求數據顯示異常:AFNetworking 回調中數組為空的排查與解決

     編輯:程式設計綜合問答

問題背景

在使用 AFNetworking 進行網絡請求時,開發者常遇到一個經典問題:在回調閉包中已成功解析數據並添加到 dataArray,但 viewDidLoad 中檢查時數組卻為空,導致表格視圖無數據顯示。這通常是由於異步請求的執行順序誤解或 UI 刷新時機不當引起的。

代碼分析

以下是典型的問題代碼結構:

@interface ViewController ()
@property (nonatomic, weak) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataArray;
@property (nonatomic, copy) NSString *url;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(0, 0, 375, 667);
    [self.view addSubview:tableView];
    self.tableView = tableView;
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.url = @"https://api.douban.com/v2/movie/top250";
    self.dataArray = [[NSMutableArray alloc] init];
    [self.tableView registerNib:[UINib nibWithNibName:@"Cell" bundle:nil] forCellReuseIdentifier:@"Cell"];
    [self testJSON];
}

- (void)testJSON {
    NSString *path = self.url;
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager GET:path parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        NSArray *movieArray = dic[@"subjects"];
        for (NSDictionary *dict in movieArray) {
            Model *model = [[Model alloc] init];
            model.movieName = dict[@"title"];
            model.movieYear = dict[@"year"];
            model.movieImage = dict[@"images"][@"large"];
            [self.dataArray addObject:model];
        }
        [_tableView reloadData];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"%@", error);
    }];
}

核心問題

代碼中存在兩個關鍵錯誤:

  1. Cell 重用標識符不一致:註冊時使用 @"Cell",但 cellForRowAtIndexPath 中卻使用 @"ID",導致無法正確復用 Cell,表格無法顯示數據。
  2. 異步請求的執行順序誤解:testJSON 發起的網絡請求是異步的,viewDidLoad 繼續執行時請求可能尚未完成,此時檢查 dataArray 自然為空。正確做法是在請求成功回調中刷新表格(代碼中已包含 [_tableView reloadData]),而非在 viewDidLoad 中判斷。

解決方案

  1. 統一 Cell 重用標識符:
    // 註冊
    [self.tableView registerNib:[UINib nibWithNibName:@"Cell" bundle:nil] forCellReuseIdentifier:@"Cell"];
    
    // 復用
    static NSString *ID = @"Cell";
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
  2. 確保在主線程刷新 UI(AFNetworking 回調通常已在主線程,但建議顯式派發):
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
    
  3. 移除 viewDidLoad 中對 dataArray 即時判斷的邏輯,信任異步回調流程。

最佳實踐建議

  • 使用現代網絡庫(如 AFNetworking 4.x+ 或 Alamofire Swift 版)簡化異步處理。
  • 採用 MVVM 或類似架構分離網絡層與視圖層,避免控制器過於臃腫。
  • 為 Cell 註冊統一管理的常量標識符,減少拼寫錯誤。

通過修正標識符不一致並理解異步請求的生命周期,即可解決數據不顯示的問題。初學者應重點掌握異步編程模式與 UITableView 復用機制,這是 iOS 開發的基石。

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