ObjC委托方法从来没有被调用 [英] ObjC delegate methods never gets called

查看:209
本文介绍了ObjC委托方法从来没有被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个类FlickrImage解析Flickr API照片响应的实例。类有一个方法getLocation,另一个API调用获取地理位置:

  NSLog(@获取位置为%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这实际上是确定的...
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];

解决方案

您的代理方法从未被调用,因为从不进行请求。当调用 callAPIMethodWithGET:时,它设置通信以在当前线程的运行循环上异步运行,然后立即返回。这样你就可以在主线程上安全地调用它,而不会阻塞。



因为你是从自己创建的线程调用方法,所以看不到主运行循环,但是你的新线程的运行循环。但是,由于您从不执行运行循环,因此不会发送消息,也不会接收到响应,并且不会调用您的委托。



您可以通过在你的新线程中调用 [[NSRunLoop currentRunLoop] run] 来解决这个问题。这将让工作发生。 但在这种情况下会更容易从不分离一个新的线程。你的程序不会阻塞,你不必担心你的委托方法需要重入。 / p>

I am creating instances of a class FlickrImage parsing a Flickr API photos response. The class has a method getLocation that does another API call to get the geolocation:

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];

I have implemented the callback method that would catch the response from the API and update the FlickrImage instance with the geolocation data - but it never gets called. Here's where the instances get created:

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];
}

The retain is there because I thought it might help solve this but it doesn't - and doesn't the NSMutableArray (flickrImages is a NSMutableArray) retain its members anyway?

EDIT I should add that the getLocation method (first code snippet) is launched in a thread: [NSThread detachNewThreadSelector:@selector(getLocation) toTarget:self withObject:nil];

解决方案

Your delegate method is never being called because the request is never being made. When you call callAPIMethodWithGET:, it sets up communications to run asynchronously on the current thread's run loop, then returns immediately. That way you can safely call it on the main thread without blocking.

Because you are calling the method from a thread you created yourself, it does not see the main run loop, but the run loop for your new thread. However, because you never execute the run loop, the messages are never sent, a response is never received, and your delegate is never called.

You could fix this by calling [[NSRunLoop currentRunLoop] run] in your new thread. That will let the work happen. But in this case would be easier to never detach a new thread in the first place. Your program won't block, and you won't have to worry about your delegate method needing to be reentrant.

这篇关于ObjC委托方法从来没有被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆