면책 조항 :이 답변의 코드는 테스트되지 않았습니다!
우선 포인터 사용이 실제로 비교 - 변환을 필요로하지 않는다는 점을 말씀 드리고 싶습니다. C 포인터 읽기 및 쓰기는 스스로 원자가됩니다. 자세한 내용은 this SO answer을 참조하십시오. ARM에서도 마찬가지입니다. 누가 알고 있기 때문에, 어쩌면 비교 및 실질 용도가, 다시 질문에 지금
NSObject * global;
NSObject * get() { return global; }
void set(NSObject * value) { OSMemoryBarrier(); global = value; }
: 당신이 원자 getter 및 setter를 구현 그래서 경우에만 다른 스레드가 완전히 초기화 된 개체를 볼 보장하기 위해 메모리 장벽을해야합니다 - 스와핑 개체. 캐스트는 여전히 가능합니다, 당신은 지금 막 다르게 선언 : 문자열 @"A"
가 기준을 상실하고, @"B"
는 ARC 모르게 두 번 참조됩니다 :
NSString * a = @"A";
NSObject * b = @"B";
OSAtomicCompareAndSwapPtrBarrier(
(__bridge void *)a,
(__bridge void *)b,
(__bridge void * *)&a);
그러나이 코드는 문제가있다. 따라서 @"A"
은 누수 될 것이며, @"B"
은 보유 카운터가 1
인 경우에만 두 번 해제되므로 범위를 벗어날 때 프로그램이 중단 될 가능성이 있습니다.
유일한 옵션은 Core Foundation 객체를 사용하는 것입니다. NSObject가 CFType을 사용하여 수신자 부담으로 연결된다는 사실을 사용할 수 있습니다. 이것에 대한 명확한 문서를 찾을 수는 없지만 상식과 실제적인 증거에서 나온 것입니다. 그래서 예. 싱글 톤을 구현하는 것이 가능합니다.
CFTypeRef instance;
Thingamabob * getInstance() {
if (!instance) {
CFTypeRef t = (__bridge_retained CFTypeRef)[Thingamabob new];
if (!OSAtomicCompareAndSwapPtrBarrier(NULL, t, &instance)) {
CFRelease(t);
}
}
return (__bridge Thingamabob *)instance;
}
감사합니다. 불행히도 이것을 유지 카운트 검사에 의존하게 만들면 스왑에 다른 비 스레드 안전 단계가 추가됩니다. 스왑의 성능상의 이점을 감안할 때 ARC로 전환하는 과정에서 잊지 않았 으면 좋겠다. 아 글쎄, 좀 더 무거운 잠금을 할거야. – FooBard