Objective-C:视图显示空表,因为API需要时间从服务器获取



我有一个TransactionViewController,在实例化期间从API获取数据,看起来像

- (id)init {
    self = [super init];
    if (self) {
        TransactionsModel *transactionsModel = [TransactionsAPI getTransactionsForYear:2014 AndMonth:9];
        self.transactionsModel = transactionsModel;
    }
    return self;
}

获取数据的API如下所示

+ (TransactionsModel *)getTransactionsForYear:(int)year AndMonth:(int)month {
    NSDictionary *transactions = [self getTransactions];
    NSLog(@"transactions: %@", transactions);
    return [[TransactionsModel alloc] initWithJson:transactions];
}

+ (NSDictionary *)getTransactions {
    AFHTTPRequestOperationManager *manager = [RestHelper getSecureManager];
    __block NSDictionary* transactions = nil;
    [manager GET:[appUrl stringByAppendingString:@"rest/transactions/2014/11"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        transactions = responseObject;
    }    failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    return transactions;
}

我正在使用AFNewtworking 2.0,其中每个调用都asynchronous,对吧?

问题如何等待显示我的Table,直到从服务器获取数据?

P.S 我是iOS编程新手,正在寻找解决这些问题的推荐方法。谢谢

您需要将完整的代码转换为异步实现。请参阅下面的示例编辑。

+ (void)getTransactionsWithCompletionHandler:^(NSDictionary *responseObject)completionHandler {
    AFHTTPRequestOperationManager *manager = [RestHelper getSecureManager];
    [manager GET:[appUrl stringByAppendingString:@"rest/transactions/2014/11"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        completionHandler((NSDictionary *)responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

您还需要在使用该方法时传递的块中调用-reloadData

- (id)init {
    self = [super init];
    if (self) {
        TransactionsModel *transactionsModel = [TransactionsAPI getTransactionsForYear:2014 AndMonth:9 completionHandler:^(NSDictionary *transactions) {
            self.transactionsModel = transactions;
            [self.tableView reloadData];
        }];
    }
}

在您的 API 中:

+ (void)getTransactionsForYear:(int)year AndMonth:(int)month completionHandler:^(TransactionsModel *transactions)completionHandler {
    [self getTransactionsWithCompletionHandler:^(NSDictionary *transactions) {
        TransactionsModel *model = [[TransactionsModel alloc] initWithJson:transactions];
        completionHandler(model);
    }];
}

使用完成块。您的getTransactions方法中有一个有用的方法:

[manager GET:[appUrl stringByAppendingString:@"rest/transactions/2014/11"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
transactions = responseObject;
--> RELOAD TABLE HERE: [tableView reloadData]; <--
.
.
.

您的表可能在另一个类中。您可以使用通知和观察者。基本上,您设置了一个侦听特定通知的观察者,并在某个时候发布通知,观察者会监听它并执行某些操作。例如:

  1. 当响应到达时发布通知(我建议你放[tableView reloadData];的地方,但如果你选择这种方式,就不要放它):

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TransactionResponseArrived" object:self userInfo:nil];

  2. 转到表视图控制器并添加一个观察器:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData:) name:@"TransactionResponseArrived" object:nil];

    请注意,您必须使用与上述相同的通知名称。

  3. 同样在表视图控制器中,创建观察者收到通知时调用的方法 ( updateData: ):

    - (void)updateData:(NSNotification *)notification { [self.tableView reloadData]; }

  4. 最后,请记住卸载观察器:

    [[NSNotificationCenter defaultCenter] removeObserver:self name:InAppPurchaseDownloadStatusUpdated object:nil];

    如果在 init 方法中添加观察器,则可以在 dealloc 方法中执行此操作。如果使用 viewWillSeem 或 viewDidSeem 来加载观察器,请使用 viewWillDisappear 或 viewDidDisappear 将其删除。

希望这有帮助!

最新更新