这可能是一个幼稚的问题,但我还是会问这个问题,因为我找不到任何可以在我脑海中解决这个问题的文档。
我正在使用 Xcode45-DP4 在设备和模拟器中运行 iOS5.1。
我有一个循环遍历一个类的多个实例的数组。在那个循环中,我在实例上使用 performSelector 来启动一个线程,该线程执行一些相对较慢的网络操作——拉取我宁愿在后台执行的数据。
[arrayOfFriends enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Friend *f = (Friend*)obj;
iOSSLog(@"%d", idx);
[f performSelectorInBackground:@selector(showDescription) withObject:nil];
-(void)fetchTwitterStatus
{
iOSSLog(@"Trying to fetch twitterstatus %@ %@", self.hash, self.twitterUserName);
[mLocalTwitterUser fetchTwitterAPIUserStatusWithScreenName:twitterUserName
withCompletionHandler:^(NSArray *arrayOfStatus, NSError *error) {
if(error) {
iOSSLog(@"%@", error);
} else {
iOSSLog(@"Got twitterstatus %@ %d", self.twitterUserName, [arrayOfStatus count]);
@synchronized(items) {
[items addObjectsFromArray:arrayOfStatus];
}
}
}];
}
在我的测试用例中有四个实例。每个实例都有它的选择器,你知道..selected。前三个肯定开始,但只有最后一个实际完成,如日志行所示,“Got twitterstatus ...”这很奇怪。
我还可以验证选择器调用的方法“fetchTwitterStatus”
我在这里缺少的多线程的基本核心是什么?
编辑:这里是 fetchTwitterAPIUserStatusWithScreenName ......这里有点,但实际上它使用 JSON 响应调用 Twitter API 端点 user_timeline。
- (void)fetchTwitterUserStatusWithScreenName:(NSString *)screenname
excludeReplies:(BOOL)excludeReplies
withCompletionHandler:(OtterTwitterSearchHandler)completionHandler
{
self.twitterAPIStatusHandler = completionHandler;
//self.fetchTwitterUserStatusHandler = completionHandler;
NSString *urlString = [NSString stringWithFormat:@"https://api.twitter.com/1/statuses/user_timeline.json?screen_name=%@&include_rts=true&include_entities=true&exclude_replies=%@&count=50", screenname, excludeReplies?@"true":@"false"];
NSURL *url = [NSURL URLWithString:urlString];
#warning this isn't the way to do it - just checking the cache for refresh of the scroller
[[ASIDownloadCache sharedCache]removeCachedDataForURL:url];
iOSSRequest *request = [[iOSSRequest alloc] initWithURL:url
parameters:nil
requestMethod:iOSSRequestMethodGET];
NSMutableDictionary *oauthParams = [NSMutableDictionary dictionary];
[oauthParams setObject:[[Twitter sharedService] apiKey] forKey:kASIOAuthConsumerKey];
[oauthParams setObject:[[Twitter sharedService] apiSecret] forKey:kASIOAuthConsumerSecret];
[oauthParams setObject:[self oAuthAccessToken] forKey:kASIOAuthTokenKey];
[oauthParams setObject:kASIOAuthSignatureMethodHMAC_SHA1 forKey:kASIOAuthSignatureMethodKey];
[oauthParams setObject:@"1.0" forKey:kASIOAuthVersionKey];
[oauthParams setObject:[self oAuthAccessTokenSecret] forKey:kASIOAuthTokenSecretKey];
request.oauth_params = oauthParams;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error) {
if (self.twitterAPIStatusHandler) {
self.twitterAPIStatusHandler(nil, error);
self.twitterAPIStatusHandler = nil;
}
} else {
NSMutableArray *recentStatusForTwitterUser = [[NSMutableArray alloc]init];
NSArray *array = [Twitter JSONFromData:responseData];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
TwitterStatus *twitterStatus = nil;
twitterStatus = [[TwitterStatus alloc]initWithDictionary:obj];
[recentStatusForTwitterUser addObject:twitterStatus];
}];
if (self.twitterAPIStatusHandler) {
self.twitterAPIStatusHandler(recentStatusForTwitterUser, nil);
self.twitterAPIStatusHandler = nil;
}
}
}];
}