3

すべての Game Center ロジックを処理するシングルトン クラスがあります。

typedef void (^GameCenterCallbackFinishUpdating)();

- (void)getAllMatches:(GameCenterCallbackFinishUpdating)onComplete
{
    [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
    {      
        //Do stuff here... 
        onComplete();
    }];
}

私が使用する別のviewControllerから:

[[GameCenterHelper sharedHelper] getAllMatches:^{

    [self.myTableView reloadData]; 

}];

アプリを使用しているときはうまく機能しますが、アプリを閉じて (バックグラウンドで) 再度起動すると、次のようになります。

    onComplete();     ---- Thread 1: EXC_BAD_ACCESS (code=2, address=0xc)

ここで何が間違っていますか?

4

2 に答える 2

10

背景情報:ブロックはオブジェクトであり、ブロックがオブジェクトであり、 nil それらを呼び出そうとすると、アプリケーションがクラッシュします。

あなたがそれを呼び出す前に、どこかでどういうわけかブロックonCompleteになります。nil次のステートメントは、ポインターのif (...)呼び出しを防ぐのに役立ちます。これにより、アプリケーションがクラッシュしなくなります。nil

if (onComplete) onComplete();
于 2013-01-11T15:25:39.513 に答える
0

よく説明してくれた@holexと@Paul.sに感謝します。メソッド parameter( ) としてブロックを送信していたのと同様の状況がありましたcompletionHandler

- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
    completion(something);
}

そして、このブロックを次のように使用している 2 つの状況があります。

[MyClass sharedInstance] callX:@"abc" withCompletionHandler:^(NSString *response) {
    if (response) {
        //do something
    }
}];

または、このブロックnilをメソッド パラメーターとして指定できます。

[MyClass sharedInstance] callX:@"abc" withCompletionHandler:nil];

ブロックがnilメソッドパラメーターとして渡された2番目のケースでは、これはcompletion()EXC_BAD_ACCESSで発生しました。したがって、@holex はブロックがオブジェクトであると述べており、いずれかのブロックが nil であり、それらを呼び出そうとすると、アプリケーションがクラッシュします。 1 つの if で多くの時間を節約できます

- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
    if (completion)
        completion(something);
}

PS: この説明はNERDS私のような人向けです。| | 'L' |

于 2016-04-15T10:01:31.453 に答える