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 を確認することで確認できます。

これが真実であるという仮定を続けます (バックグラウンド スレッドで実行されていました)。

この呼び出しは、[ApplicationDelegate.facebook requestWithGraphPath:@"me/friends" andDelegate:self];ほとんどの場合、メイン スレッドで発生する必要があります。この理由は、おそらく、基になる呼び出しが呼び出しNSURLConnectionを行うために を使用しているためです。接続はバックグラウンド スレッドで行われますが、すべてのデリゲート呼び出しはバックグラウンド スレッドではなく、メイン スレッドで行う必要があります。callandDelegate:selfを使用すると、メイン スレッドではなく、バックグラウンド スレッドでオブジェクトをデリゲートとして登録します。

これが、現在のソリューションでその問題が修正される理由です。

ハッピーコーディング!

于 2013-08-19T20:05:33.190 に答える
0

次を発行することで、問題を回避できました。

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

なぜこれがこのように機能するのかを知ることは素晴らしいことです。

于 2012-10-01T23:44:02.467 に答える