SimpleURLConnections 샘플 코드를 보게 되면 예제 중 스트림을 사용하여 파일 전송하는 부분이 있다
이때 In/Out 스트림을 연결하기 위해 createBoundInputStream 라는 이름의 메소드를 사용하는데
ios4 에서 정상 동작하는데 ios5 에서는 업로드를 실행하면 크래시를 유발시킨다.
코드 중 CFTypeRef 를 id 타입으로 형변환을 시켜주는 NSMakeCollectable 이라는 함수를 사용하는데
이 함수를 사용하고 난 뒤 autorelease를 붙여 retainCount를 유지시켜준다.
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
하지만 ios5에서는 위 구문이 오류를 일으킨다.
참고 : http://andpdas.com/wp-content/uploads/2011/06/ARCProgrammingGuide.pdf
원인은 io5에서 retain/release 의 정책이 변경되면서 위 구문에서 생성된 inputStreamPtr 객체를 release가 한번 더 일어 나는 것이다.
이로 인해 retainCount가 맞지 않아 앱이 종료되어버린다.
이를 해결하기 위해 인터넷 검색 결과
*inputStreamPtr = objc_unretainedObject(readStream);
구문을 사용하면 문제를 해결할 수있다. 실제로 위 구문으로 변경뒤 컴파일 했을때 정상 동작을 확인 하였다.
하지만 여기서 문제가 또 발생되었는데 xcode4.3 이상의 버전에서만 objc_unretainedObject 함수가 정의되어있다. -_-;;
그러다 보니 xcode4.0 이 메인 개발환경인 상태에서는 위 함수가 정의되어있지 않아 컴파일 오류가 발생한다. ㅠㅠ
이를 해결하기 위해 결국 objc_unretainedObject 가 정의되어있는지 #ifdef 구문으로 확인하는 것으로 해결을 하였다
#ifdef objc_unretainedObject
if (inputStreamPtr != NULL) {
*inputStreamPtr = objc_unretainedObject(readStream);
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = objc_unretainedObject(writeStream);
}
#else
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
if(NaOSVersion() >= 5.0){
[*inputStreamPtr retain];
}
#endif
*inputStreamPtr = objc_unretainedObject(readStream);
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = objc_unretainedObject(writeStream);
}
#else
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
if(NaOSVersion() >= 5.0){
[*inputStreamPtr retain];
}
#endif
'iOS' 카테고리의 다른 글
UIImage 회전 관련 링크 (0) | 2011.10.11 |
---|---|
simbolicatecrash 위치 (0) | 2011.10.06 |
NSOperation 개발팁 (0) | 2011.09.27 |
NSString 조합형, 완성형 문제 (0) | 2011.08.31 |
SecItemCopyMatching 메모리릭 (0) | 2011.08.17 |