UIView as dictionary key?

后端 未结 3 870
無奈伤痛
無奈伤痛 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 <objc/runtime.h>
    
    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.

    0 讨论(0)
  • 2021-02-11 21:46

    Here is the actual code (based on the answer by luvieere and further suggestion by Yar):

    // create dictionary
    NSMutableDictionary* dict = [NSMutableDictionary new];
    // set value
    UIView* view = [UILabel new];
    dict[[NSValue valueWithNonretainedObject:view]] = @"foo";
    // get value
    NSString* foo = dict[[NSValue valueWithNonretainedObject:view]];
    
    0 讨论(0)
  • 2021-02-11 21:53

    You can use an NSValue holding the pointer to the UIView and use this as key. NSValues are copyable. but, if the view is destroyed, the NSValue will hold a junk pointer.

    0 讨论(0)
提交回复
热议问题