我正在创建解析Flickr API照片响应的类FlickrImage的实例。该类有一个方法getLocation,它执行另一个API调用以获取地理位置:
NSLog(@"getting location for %i",self.ID);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
OFFlickrAPIRequest *flickrAPIRequest = [[OFFlickrAPIRequest alloc] initWithAPIContext[appDelegate sharedDelegate].flickrAPIContext];
[flickrAPIRequest setDelegate:self];
NSString *flickrAPIMethodToCall = @"flickr.photos.geo.getLocation";
NSDictionary *requestArguments = [[NSDictionary alloc] initWithObjectsAndKeys:FLICKR_API_KEY,@"api_key",self.ID,@"photo_id",nil];
[flickrAPIRequest callAPIMethodWithGET:flickrAPIMethodToCall arguments:requestArguments];
[pool release];
我已经实现了回调方法,该方法将捕获API的响应并使用地理位置数据更新FlickrImage实例 - 但它永远不会被调用。这是实例创建的地方:
NSDictionary *photosDictionary = [inResponseDictionary valueForKeyPath:@"photos.photo"];
NSDictionary *photoDictionary;
FlickrImage *flickrImage;
for (photoDictionary in photosDictionary) {
flickrImage = [[FlickrImage alloc] init];
flickrImage.thumbnailURL = [[appDelegate sharedDelegate].flickrAPIContext photoSourceURLFromDictionary:photoDictionary size:OFFlickrThumbnailSize];
flickrImage.hasLocation = TRUE; // TODO this is actually to be determined...
flickrImage.ID = [NSString stringWithFormat:@"%@",[photoDictionary valueForKeyPath:@"id"]];
flickrImage.owner = [photoDictionary valueForKeyPath:@"owner"];
flickrImage.title = [photoDictionary valueForKeyPath:@"title"];
[self.flickrImages addObject:[flickrImage retain]];
[flickrImage release];
[photoDictionary release];
}
retain
是因为我认为它可能有助于解决这个问题,但它没有 - 并且NSMutableArray(flickrImages是NSMutableArray)是否仍然保留其成员?
编辑我应该补充说,getLocation
方法(第一个代码片段)是在一个线程中启动的:
[NSThread detachNewThreadSelector:@selector(getLocation)toTarget:self withObject:nil];
答案 0 :(得分:2)
永远不会调用您的委托方法,因为永远不会发出请求。当您调用callAPIMethodWithGET:
时,它会设置通信以在当前线程的运行循环中异步运行,然后立即返回。这样你就可以安全地在主线程上调用它而不会阻塞。
因为您是从自己创建的线程调用该方法,所以它不会看到主运行循环,而是新线程的运行循环。但是,因为您从不执行运行循环,所以永远不会发送消息,永远不会收到响应,也不会调用您的委托。
您可以通过在新主题中调用[[NSRunLoop currentRunLoop] run]
来解决此问题。这将使工作成功。 但是在这种情况下,首先永远不会分离新线程。您的程序不会阻塞,您也不必担心您的委托方法需要重入。< / p>
答案 1 :(得分:1)
我在另一个线程上请求和解析XML时遇到了这个问题我的解决方案就是这样做:
while([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:start] && !isFinished){
}
其中start = [NSDate dateWithTimeIntervalSinceNow:3];
这基本上是超时,因此它不会永久存在,并且在我的解析完成时isFinished
设置为true。
答案 2 :(得分:0)
我不熟悉这些闪烁的API包装器,但是在这段代码中:
NSDictionary *requestArguments = [[NSDictionary alloc] initWithObjectsAndKeys:FLICKR_API_KEY,@"api_key",self.ID,@"photo_id",nil];
你确定FLICKR_API_KEY和self.ID都不是零吗?如果它们中的任何一个为零,那么你最终会得到一个字典,其中的项目数量少于你想要的数量。
答案 3 :(得分:0)
你能发布你已实现的回调方法 - 这可能只是一个简单的错字,因为如果委托没有实现所需的回调,OFFlickrAPIRequest
似乎不会做任何事情。 / p>
您是否还实施了flickrAPIRequest:didFailWithError:
以查看API调用是否返回了错误?
答案 4 :(得分:0)
好的,在上面的一些建议的帮助下,我确实解决了它。
retain
,因为它确实造成了内存泄漏。它从一开始看起来并不正确,所以我对此的直觉是值得的,这是一件好事;)谢谢大家。
答案 5 :(得分:-1)
OFFlickrAPIRequest的setDelegate方法不会像它应该保留委托。这意味着只要请求是(或修补类以正确拥有自己的引用),就会卡住以确保您的委托处于活动状态。