UIView as dictionary key?

后端 未结 3 867
無奈伤痛
無奈伤痛 2021-02-11 20:57

I want to have a NSDictionary that maps from UIViews to something else.

However, since UIViews do not implement the NSCopying pro

3条回答
  •  执念已碎
    2021-02-11 21:42

    Although this isn't really what they're intended for, you could whip up a functional dictionary-like interface using Associative References:

    static char associate_key;
    void setValueForUIView(UIView * view, id val){
        objc_setAssociatedObject(view, &associate_key, val, OBJC_ASSOCIATION_RETAIN);
    }
    
    id valueForUIView(UIView * view){
        return objc_getAssociatedObject(view, &associate_key);
    }
    

    You could even wrap this up in a class ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable*; in that case you might want to retain the views that you use as keys.

    Something like this (untested):

    #import "ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable.h"
    #import 
    
    static char associate_key;
    
    @implementation ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable
    
    - (void)setObject: (id)obj forKey: (id)key
    {
        // Remove association and release key if obj is nil but something was
        // previously set
        if( !obj ){
            if( [self objectForKey:key] ){
                objc_setAssociatedObject(key, &associate_key, nil, OBJC_ASSOCIATION_RETAIN);
                [key release];
    
            }
            return;
        }
    
        [key retain];
        // retain/release for obj is handled by associated objects functions
        objc_setAssociatedObject(key, &associate_key, obj, OBJC_ASSOCIATION_RETAIN);
    }
    
    - (id)objectForKey: (id)key 
    {
        return objc_getAssociatedObject(key, &associate_key);
    }
    
    @end
    

    *The name may need some work.

提交回复
热议问题