我有点被困2天了。我正在尝试使用新的Twitter-Fabric-Kit(我遵循本指南https://dev.twitter.com/twitter-kit/ios/show-tweets)显示带有twitter用户时间线的UITableView。 我尝试这样做:通过JSON从特定用户获取Tweet-ID并将其放入实例变量中。这部分正在运作。问题 - 我到目前为止已经知道了 - 是数组在完成处理程序中传递给实例变量但似乎是异步运行。我已经尝试用GCD解决这个问题,但我没有运气。也许有人可以指出正确的方向,甚至我的解决方案是垃圾,并且有更好的方法; - )
#import "TweetTableViewController.h"
static NSString * const TweetTableReuseIdentifier = @"TwitterCell";
@interface TweetTableViewController ()
@property (nonatomic, strong) NSArray *tweetArray;
@property (nonatomic, strong) TWTRTweetTableViewCell *prototypeCell;
@end
@implementation TweetTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createTweetArray];
// .... tableView setup is here ...
// If I uncomment the next line the whole thing works!
// NSArray *test = @[@"517330786857795584", @"516652595021352960"];
__weak typeof(self) weakSelf = self;
[[[Twitter sharedInstance]APIClient]loadTweetsWithIDs:self.tweetArray completion:^(NSArray *tweets, NSError *error) {
if (tweets) {
typeof(self) strongSelf = weakSelf;
strongSelf.tweetArray = tweets;
[strongSelf.tableView reloadData];
} else {
NSLog(@"Failed to load tweet: %@", [error localizedDescription]);
}
}];
}
- (void)createTweetArray {
NSMutableArray *tempArray = [NSMutableArray array];
[[Twitter sharedInstance]logInGuestWithCompletion:^(TWTRGuestSession *guestSession, NSError *error) {
if (guestSession) {
NSString *timeline = @"https://api.twitter.com/1.1/statuses/user_timeline.json";
NSDictionary *parameters = @{@"user_id" : @"345330869"};
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance]APIClient]URLRequestWithMethod:@"GET"
URL:timeline
parameters:parameters
error:&clientError];
if (request) {
[[[Twitter sharedInstance]APIClient]sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data) {
NSError *jsonError;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
for (NSDictionary *dic in json) {
[tempArray addObject:[dic objectForKey:@"id_str"]];
}
[self handleJSONData:tempArray];
} else {
NSLog(@"Error: %@", connectionError);
}
}];
} else {
NSLog(@"Error: %@", clientError);
}
}
}];
}
- (void)handleJSONData:(NSMutableArray *)array {
self.tweetArray = [NSArray arrayWithArray:array];
NSLog(@" %@", self.tweetArray);
}
当我使用此代码运行我的应用程序时,我在控制台中获得了以下日志:
2014-11-10 22:08:41.447 [65550:3869433] numberOfSectionsInTableView
2014-11-10 22:08:41.448 [65550:3869433] numberOfSectionsInTableView
2014-11-10 22:08:41.448 [65550:3869433] numberOfRowsInSection: 0
2014-11-10 22:08:41.448 [65550:3869433] numberOfSectionsInTableView
2014-11-10 22:08:41.448 [65550:3869433] numberOfRowsInSection: 0
2014-11-10 22:08:41.449 [65550:3869433] numberOfSectionsInTableView
2014-11-10 22:08:41.450 [65550:3869433] numberOfRowsInSection: 0
2014-11-10 22:08:43.426 [65550:3869433] (
517330786857795584,
516652595021352960,
514841221907243008,
513704220600848384,
513598624706875392,
513598609603178496,
513598594017132544,
513598581471969280,
513598566502502400,
513229247117545472,
511424250138611713,
509025219584212992,
505655616338407424,
500357644226285568,
474861008314322944,
469938745438109697,
468465457750888449,
464706315924041728,
464704566492418048,
457148030731694080
)
self.tweetArray数组应该用于numberOfRowsInSection以及数据源,但该块似乎要完成到很晚。如前所述,我尝试了dispatch_async和dispatch_sync,但似乎没有任何工作。我最后的想法是handleJSONData:方法中的[self.tableView reloadData],但是我的应用程序崩溃了。使用静态数组,tableView正在运行......
感谢您的投入,我真的被困在这里......
答案 0 :(得分:0)
在handleJSONData:方法中设置断点并验证它是否在主队列上运行。
如果它没有在主队列上运行,则无法更新UI,例如在self.tableView上调用reloadData
要在主队列上运行更新,您可以使用GCD:
dispatch_async(dispatch_get_main_queue(),
^{
[self.tableView reloadData]
});
或NSOperationQueue:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadData]
}];
答案 1 :(得分:0)
完成处理程序将始终在调用它的代码完成后完成。这就是异步代码的工作原理。是的,您应该重建数据结构,在完成处理程序中提供tableview的数据源,然后调用reloadData。如果由于某个错误导致它崩溃,那不是因为它做错了。