2012-01-13 1 views
3

ARC 및 메모리 관련 충돌로 도움을받을 수있는 사람이 있습니까?멤버 변수로 블록 포인터를 사용할 때 iOS에서 ARC 관련 충돌이 발생했습니다.

나는 블록 포인터를 저장하는 멤버 변수와 클래스 LTRequest이 : 나는 성공의 경우 블록을 호출

-(void)addOKBlock:(APICallOKBlock)okBlock 
{ 
    self.okCB = okBlock; 
} 

:

그 변수를 초기화하는

typedef void (^APICallOKBlock)(id); 

@interface LTRequest : NSObject 
@property (nonatomic, strong) APICallOKBlock okCB; 
@end 

코드를

-(void)apiCallCompletedWithResult:(id)result 
{ 
    if(self.okCB != nil) 
    { 
     self.okCB(result); 
    } 
} 

참조 용 블록은 다음과 같습니다.

APICallOKBlock okBlock = ^(id result) 
{ 
    [self handleAPICallCompleted:result]; 
}; 

API 호출을 예약 한 개체에 정의 된 함수를 호출하지만 그 부분은 중요하지 않습니다. 중요한 것은 API 호출이 성공한 후에 apiCallCompletedWithResult이 호출 될 때 일어나는 일입니다. 나는의 블록을 저장하는 대신 strongunsafe_unretained를 사용하려고

Thread 6 name: Dispatch queue: com.apple.root.low-priority 
Thread 6 Crashed: 
0 libobjc.A.dylib     0x300bad9c objc_release + 12 
1 libobjc.A.dylib     0x300c6c00 objc_storeStrong + 24 
2 SomeAppName      0x00055688 -[LTRequest .cxx_destruct] (LTRequest.m:12) 
3 libobjc.A.dylib     0x300bba66 object_cxxDestructFromClass + 50 
4 libobjc.A.dylib     0x300bba2c object_cxxDestruct + 8 
5 libobjc.A.dylib     0x300b99ac objc_destructInstance + 20 

: 그리고 발생하는 블록이 호출되는 것을하지만 응용 프로그램은 그후 요청 객체 LTRequest가 해제 될때 충돌 (SomeAppName는 우리의 응용 프로그램입니다) LTRequest 목적 :

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x300b9eda objc_retain + 10 
1 libobjc.A.dylib     0x300c6bde objc_retainAutoreleasedReturnValue + 34 
2 SomeAppName      0x00054f90 -[LTRequest apiCallCompletedWithResult:] (LTRequest.m:84) 
3 SomeAppName      0x0002f8aa __29-[LTServerProxy makeAPICall:]_block_invoke_0 (LTServerProxy.m:154) 

// file LTRequest.m 

line 84 if(self.okCB != nil) 
line 85 { 
line 86  self.okCB(result); 
line 87 } 
: 충돌이있는 경우와 라인에 정확히 일어나는 경우

@property (nonatomic, unsafe_unretained) APICallOKBlock okCB; 

블록에 대한 포인터를 올바르게 사용하고 있으며 충돌을 일으키지 않으려면 어떻게 호출해야합니까?

일부 정보 : iOS SDK 5.0을 사용하고 있으며 배포 대상은 4.0이며 장치 iPhone은 ARC가 전체 프로젝트에 사용됩니다.

답변

15

당신은 속성이 copy보다는 retain 할 것을 권장합니다

@property (nonatomic, copy) APICallOKBlock okCB; 
+0

감사합니다. 왜 개발자 문서가 새롭고 강한/약한 속성들만 일관되게 언급하고 오래된 것들 중 일부는 여전히 필요하다는 것을 상기시키지 않는지 확실하지 않습니다. – Amiramix

+0

http://blog.refractalize.org/post/10476042560/copy-vs-retain-for-objective-c-blocks에는 왜 그런지에 대한 메모와 더욱 자세한 기사에 대한 링크가 있습니다. –

+0

이것은 나를 구해주었습니다! 나는 내가 비 원자 학적으로 표시 한 NSNumber를 가지고 있었고, 비 원자형 대신 강력하게 지정했습니다! 큰 차이! 감사! – iOS4Life

2

당신은 클래스 인스턴스의 인스턴스를 저장할 때 블록을 복사해야합니다.

+1

감사합니다. 좋은 제안이지만 copy 속성 속성을 설정하는 것이 더 간단합니다 (변수가 할당 될 때 각 위치를 복사 할 필요가 없습니다) – Amiramix