问题
I'm wondering if it's possible to have something similar to ActionScript 3's Dictionary
object with weak keys in Objective-C. I want to be able to 'attach' an instance of a class to other arbitrary instances.
Example;
MetaData *meta = [MetaData metaDataForObject:someObject];
meta.whatever = foo;
And later:
foo = [MetaData metaDataForObject:someObject].whatever;
[foo doStuff];
The tricky part is that after the objected referenced by someObject
is dealloc'd, I want the object referenced by meta
to be released (and dealloc'd, assuming no client code has retained it).
Possible? I took a look at +[NSValue valueWithNonretainedObject:]
but I'm not sure if this is what I want because there when I later query -[NSValue nonretainedObjectValue]
it seems like I would get a pointer to garbage (how could NSValue zero the pointer when the object was dealloc'd?).
Thanks,
benjamin
Update 23 September 2011: I believe the way to do this is with objc_setAssociatedObject
and related functions. See the Objective-C Runtime Reference.
回答1:
It sounds like what you're asking for is the ability to react to a weak-referenced instance variable being deallocated. You can certainly use the __weak
attribute (with GC enabled) to create a weak reference, but there's no built-in mechanism to catch when such an attribute is zeroed after its target is GCed.
If you really want this, your best bet is to use the same mechanism Apple's Key-Value Observing uses: method swizzling. Maintain a global table (such as a NSHashMap
or NSMapTable
) mapping objects to their corresponding metadata objects, then replace the dealloc
/finalize
methods in the class of the object you're attaching to with versions that look up the corresponding metadata object in the table and send a message to tear it down. (You also need another table or two that maps classes to their original dealloc
/finalize
methods.) JRSwizzle provides a nice interface to swizzling.
If you want to to be really fancy, instead of overwriting the dealloc
/finalize
for all objects of the target class, you can create a proxy class and reassign the isa
pointer for just that class, such that there's no performance hit on deallocation for the objects you're not watching. (KVO does this, too.)
回答2:
Are you looking for NSHashMap perhaps? It does zeroing references.
来源:https://stackoverflow.com/questions/735551/weak-keyed-dictionary-in-objective-c