2009-04-09 3 views
3

Objective-C의 약한 키를 가진 ActionScript 3의 Dictionary 개체와 유사한 것을 가질 수 있는지 궁금합니다. 클래스의 인스턴스를 다른 임의의 인스턴스에 '첨부'할 수 있기를 원합니다.Objective-C의 weak-keyed dictionary

예;

MetaData *meta = [MetaData metaDataForObject:someObject]; 
meta.whatever = foo; 

이상 :

foo = [MetaData metaDataForObject:someObject].whatever; 
[foo doStuff]; 

까다로운 부분은이 someObject에 의해 참조 이의를 제기 한 후, 나는 가정, meta가 참조하는 객체가 해제 (그리고 dealloc'd 싶은 dealloc'd된다는 것이다 클라이언트 코드는 그것을 유지하지 않는다).

가능합니까? 나는 +[NSValue valueWithNonretainedObject:]을 보았다. 그러나 이것이 내가 나중에 쿼리 할 때 내가 원하는 이유인지 확실하지 않다. -[NSValue nonretainedObjectValue] 쓰레기에 대한 포인터를 얻을 수있는 것처럼 보인다 (객체가 dealloc'd되었을 때 어떻게 NSValue 0 포인터가 될 수 있었 을까?).

감사합니다,

벤자민

업데이트 2011년 9월 23일 : 나는이 작업을 수행 할 수있는 방법은 objc_setAssociatedObject 및 관련 기능을 믿습니다. Objective-C Runtime Reference을 참조하십시오.

답변

4

약한 참조 된 인스턴스 변수에 대응할 수있는 기능이 할당 해제되는 것 같습니다. __weak 속성 (GC가 활성화 된 상태)을 사용하여 약한 참조를 만들 수는 있지만 대상이 GCed 된 후에 해당 속성이 0으로 설정되면이를 잡을 수있는 기본 제공 메커니즘이 없습니다.

정말로 이것을 원한다면, 가장 좋은 방법은 애플의 키 - 값 관측법 인 메서드 스위 즐링 (sweeping)과 동일한 메커니즘을 사용하는 것입니다. 개체를 해당 메타 데이터 개체에 매핑하는 전역 테이블 (예 : NSHashMap 또는 NSMapTable)을 유지 한 다음 첨부 할 개체 클래스의 dealloc/finalize 메서드를 테이블의 해당 메타 데이터 개체를 조회하는 버전으로 바꿉니다 그것을 찢어 버리기 위해 메시지를 보냅니다. (클래스를 원래의 dealloc/finalize 메쏘드로 매핑하는 또 다른 테이블이 필요합니다. JRSwizzle은 멋진 인터페이스를 제공합니다. 대신 대상 클래스의 모든 객체에 대한 dealloc/finalize를 덮어 쓰기, 정말 멋진 일을하려면

, 당신은 어떤 성능 저하가 없습니다 있도록, 단지 클래스의 isa 포인터를 프록시 클래스를 생성하고 할당 할 수 있습니다 보고 있지 않은 객체에 대한 할당 해제 (KVO도이 작업을 수행합니다.)

+0

방법 swizzling 꽤 똑바로 소리. 당신이 말한 isa-swizzling 기술에 대해 자세히 설명해 주시겠습니까? 내가 이해하면 객체의 클래스를 효과적으로 변경하여 dealloc의 새로운 구현을 제공 할 수 있습니까? – bvanderveen

+0

네, 맞습니다. –

+0

또한 10.5에는이를 위해 사용할 수있는 함수가 있으며, 이는 앞으로 유용 할 것입니다. http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/ c/func/object_setClass –

1

아마도 NSHashMap을 찾고 계십니까? 그것은 참조를 zeroing 않습니다.

+0

iPhone 용으로 개발 중이며 불행히도 NSHashMap을 사용할 수없는 것 같습니다. – bvanderveen