I was trying to work on xcode and ios5 and I have a TWRequest to bring down tweets using the Twitter Api. However, I am confused about how blocks work in iOS5. For example in this code
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSArray* firstParse = [dictionary objectForKey:@"results"];
for (NSDictionary *post in firstParse) {
Tweet *tweetMessage = [[Tweet alloc] init];
tweetMessage.message = [post objectForKey:@"text"];
tweetMessage.user = [post objectForKey:@"from_user"];
[tweets addObject:tweetMessage];
}
}];
NSLog(@"%@",[tweets count]);
Assuming that I have a tweets = [NSMutableArray arrayWithCapacity:25]; call somewhere up top.
However, every time I do this, the count is always at zero. After doing some testing, I realized that the block code was running after the NSLog was running signifying that the code did not run from top down as I was use to.
Does anyone know how to fix such an issue?
I also tried this later example because I was trying to move the tweets into a viewController that has an array object
tweetViewController.tweets = [NSMutableArray arrayWithCapacity:25];
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSArray* firstParse = [dictionary objectForKey:@"results"];
for (NSDictionary *post in firstParse)
{
Tweet *tweetMessage = [[Tweet alloc] init];
tweetMessage.message = [post objectForKey:@"text"];
tweetMessage.user = [post objectForKey:@"from_user"];
[tweetViewController.tweets addObject:tweetMessage];
NSLog(@"%d",[tweets count]);
//NSLog(@"%@: %@", [post objectForKey:@"from_user"], [post objectForKey:@"text"]);
}
}];
Tweet *tweetMessage = [[Tweet alloc] init];
tweetMessage.message = @"HELLO";
tweetMessage.user = @"HELLO";
[tweetViewController.tweets addObject:tweetMessage];
return YES;
The Hello messages display properly but the ones in the block do not.
Don’t. Basically, focus on making your code asynchronous. This’ll be better for the user (the UI will be more smooth) and easier for the developer (yes, really!)
Do everything that’s related to loading the tweets in the block instead of after it. Place your
NSLogin the block instead of outside it. Once you’re done loading all the tweets, simply call[tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];or something else, to update the UI.Make sure to avoid using the
nonatomicflag on the property that stores thetweets. You want to avoid invalid cross-thread access.