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

Posted

技术标签:

【中文标题】Objective-C:视图显示空表,因为 API 需要时间从服务器获取【英文标题】:Objective-C: View displays empty Table since API takes time to fetch from Server 【发布时间】:2014-11-16 20:48:58 【问题描述】:

我有一个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 编程的新手,正在寻找解决这些问题的推荐方法。谢谢

【问题讨论】:

【参考方案1】:

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

+ (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);
    ];

【讨论】:

【参考方案2】:

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

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

您的桌子可能在另一个班级。您可以使用通知和观察者。基本上,你设置了一个监听器来监听一个特定的通知,并且在某个时候,你发布一个通知,观察者监听它并做一些事情。例如:

    在响应到达时发布通知(我建议您放置 [tableView reloadData]; 的位置相同,但如果您选择这种方式,请不要放置):

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

    转到您的表 viewController 并添加一个观察者:

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

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

    同样在您的表 viewController 中,创建观察者收到通知时调用的方法 (updateData:):

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

    最后,记得卸载观察者:

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

    如果您在 init 方法中添加观察者,您可以在您的 dealloc 方法中执行此操作。如果您使用 viewWillAppear 或 viewDidAppear 加载观察者,请使用 viewWillDisappear 或 viewDidDisappear 将其移除。

希望这会有所帮助!

【讨论】:

以上是关于Objective-C:视图显示空表,因为 API 需要时间从服务器获取的主要内容,如果未能解决你的问题,请参考以下文章

从数据库中获取记录时显示空表视图

Objective-C 将图像缩略图附加到视图的末尾

IOS/Objective-C:子视图的子视图不显示

在视图控制器上不显示视图控制器 - Swift / Objective-C

主从情节提要:表格视图不显示单元格(Objective-C)

带有静态单元格的 UITableViewController 显示为空白