0

我有一个发送请求并有一个委托响应者的方法。该方法由 KVO 响应程序调用。当我从 viewDidLoad 调用它时,代码工作正常,但是当我从 KVO 方法发出请求时,它不会触发委托方法。

这是我的 KVO 响应者:

//observe app delegates userdata to check for when user data is available or data is changed
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"userData"] )
    {
        //goto facebook logic
        [self FBFriendSuggester];
    }
}

及其调用的方法:

-(void)FBFriendSuggester
{
    NSDictionary * fb_credentials = nil;
    if([prefs objectForKey:@"facebookCredentials"])
    {
        fb_credentials = [prefs objectForKey:@"facebookCredentials"];
        if ([fb_credentials objectForKey:@"expiry"] && [fb_credentials objectForKey:@"fbtoken"]) {
            NSLog(@"found stored Facebook credentials.");
            ApplicationDelegate.facebook.accessToken = [fb_credentials objectForKey:@"fbtoken"];
            ApplicationDelegate.facebook.expirationDate = [fb_credentials objectForKey:@"expiry"];
        }
    }
    if ([ApplicationDelegate.facebook isSessionValid]) {
        printf("_valid facebook\n");
        [ApplicationDelegate.facebook requestWithGraphPath:@"me/friends" andDelegate:self];
    }else
        printf("_invalid facebook\n");
}

和委托方法:

- (void)request:(FBRequest *)request didLoad:(id)result{
    NSLog(@"result2:%@",result);

    NSDictionary * rawObject = result;
    NSArray * dataArray = [rawObject objectForKey:@"data"];

    for (NSDictionary * f in dataArray) {
        [friends addObject:[[KNSelectorItem alloc] initWithDisplayValue:[f objectForKey:@"name"]
                                                            selectValue:[f objectForKey:@"id"]
                                                               imageUrl:[NSString stringWithFormat:@"http://graph.facebook.com/%@/picture?type=square", [f objectForKey:@"id"]]]];
    }
    [friends sortUsingSelector:@selector(compareByDisplayValue:)];
    [self pickerPopup:self];
}

在这种情况下不会调用委托方法,但是当我直接从控制器调用 -(void)FBFriendSuggester 时它确实可以正常工作。我不知道该怎么做,我尝试设置一个通知来响应,希望它会触发委托,但这也不起作用。

4

2 回答 2

1

我知道这已经很老了,但要说明发生这种情况的原因,KVO 通知会在发生更改的线程上发送。因此,如果后台线程对 AppDelegate 上的属性进行更改,则通知更改也会发生在后台线程上。

因此,在您的代码上下文中,您-(void)FBFriendSuggester很可能在后台线程中被调用。您可以通过在代码中设置断点并查看 Debug Navigator 来确认这一点。

我将继续假设这是真的(它在后台线程中运行)。

This call, [ApplicationDelegate.facebook requestWithGraphPath:@"me/friends" andDelegate:self]; most likely needs to occur on the main thread. Reason for this is probably the underlying calls are using an NSURLConnection to make the call. The connections are made on background threads, but all delegate calls MUST be made back on the main thread, NOT a background thread. With the call andDelegate:self, its registering the object as a delegate on the background thread, instead of the main thread.

This is why your current solution fixes that issue.

Happy Coding!

于 2013-08-19T20:05:33.190 回答
0

我能够通过发出以下命令来解决我的问题:

[self performSelectorOnMainThread:@selector(FBFriendSuggester) withObject:nil waitUntilDone:NO];

很高兴知道为什么会这样。

于 2012-10-01T23:44:02.467 回答