2015-01-02 4 views
5

이 질문은 ios NSError types과 유사하지만 거기에 설명 된 해결책이 작동하지 않으며 내가 필요한 것.'NSError * const autoreleasing *'유형의 매개 변수에 'NSError * const __strong *'을 보내면 포인터의 유지/해제 속성이 변경됩니다.

필자는 비동기 호출을 수행하고 완료 블록을 호출하는 메서드를 사용합니다.

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

패스 오류, 참조가 아닌, 즉 변화 내가 완료 블록에 ** NSError를 통과 할 때,이 오류가 발생합니다 블록 서명을 void (^)(AKAgentProfile * agentProfile, NSError * error)으로 설정하고 &error 대신 error을 전달하십시오.

-1

당신은 오류가 블록에 다시

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

에 인수로 정의하고있다, 나는 당신이 같은 블록에서 하나의 이름을 변경 제안 :

+(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); 
     }); 

    }); 
}