2015-01-02 5 views
5

この質問はios NSError typesと似ていますが、そこに記載されている解決策は機能しませんでした。かなり必要なものです。'NSError * const autoreleasing *'型のパラメータに 'NSError * const __strong *'を送信すると、ポインタの保持/解放のプロパティが変更されます

私は、非同期呼び出しを実行してから完了ブロックを呼び出すメソッドを持っています。私は完了ブロックに** NSErrorを渡すしようとすると、私はこのエラーを取得する:次のように

Sending 'NSError *const __strong *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer

コードは次のとおりです。値ではなく、参照することにより

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 
{ 
    dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(requestQueue, ^{ 
     NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid]; 
     NSURL *url = [NSURL URLWithString:parameterizedUrl]; 
     NSData *data = [NSData dataWithContentsOfURL:url]; 

     NSError * error = nil; 

     AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock(agentProfile,&error); 
     }); 

    }); 
} 
+2

あなたは、ポインタとポインタの対の関係を誤解しています。 – Andy

+0

Andy:私はそれが後でかなり明白であることを理解するために私をしばらく時間がかかることを認めます! –

答えて

5

あなたの完了のブロック引数は総ナンセンスです。

コールスタック上に変数NSError * errがあります。

次に、errのアドレスをメインスレッドで呼び出される完了ブロックに渡そうとします。補完ブロックが呼び出されるまでには、あなたの関数は長い間返されており、&というエラーはごみです。完成ブロックがそこに何かを格納しようとすると、まるで誤った変数がスタック上にあったNSError *が格納され、完全に無関係なメソッドの貴重なデータを上書きする可能性があります。

これはコールバックブロックでは機能しません。

5

パスエラー、すなわち変更ブロック署名をvoid (^)(AKAgentProfile * agentProfile, NSError * error)に設定し、&errorの代わりにerrorを渡します。

-1

あなたはエラーがブロック内に再び

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 

に引数として定義されていて、私はあなたのようなブロック内の1の名前を変更するお勧め:

+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock 
{ 
    dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(requestQueue, ^{ 
     NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid]; 
     NSURL *url = [NSURL URLWithString:parameterizedUrl]; 
     NSData *data = [NSData dataWithContentsOfURL:url]; 

     NSError * err = nil; 

     AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionBlock(agentProfile,&err); 
     }); 

    }); 
} 
関連する問題