UIView作为字典键?

mru*_*ueg 27 iphone objective-c nsdictionary uiview nscopying

我希望有一个NSDictionaryUIViews 映射到其他东西.

但是,由于UIViews没有实现NSCopying协议,我不能直接将它们用作字典键.

luv*_*ere 30

您可以使用NSValue指针指向UIView并将其用作键.NSValues 是可复制的.但是,如果视图被破坏,NSValue它将持有一个垃圾指针.

  • 现在使用ARC,你必须使用`valueWithNonretainedObject`. (7认同)

Rok*_*iša 17

这是实际的代码(基于luvieere的回答和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]];
Run Code Online (Sandbox Code Playgroud)


Jos*_*ell 5

尽管这并不是它们真正的目的,但您可以使用关联引用创建一个类似字典的功能界面:

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);
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以将其包装在类ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable*;中。在这种情况下,您可能希望保留用作键的视图。

像这样的东西(未经测试):

#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
Run Code Online (Sandbox Code Playgroud)

*名称可能需要一些修改。