从完成处理程序返回NSArray到ivar

时间:2014-11-10 21:13:00

标签: ios objective-c json twitter objective-c-blocks

我有点被困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正在运行......

感谢您的投入,我真的被困在这里......

2 个答案:

答案 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。如果由于某个错误导致它崩溃,那不是因为它做错了。