使用UIImageView作为NSMutableDictionary中的键来查找布尔值

时间:2013-02-17 21:26:40

标签: objective-c uiimageview nsdictionary nsmutabledictionary

标题几乎说明了一切。我想创建一个NSMutableDictionary,我使用UIImageViews来查找布尔值。这是它的样子:

我的.h文件:

@interface ViewController : UIViewController{
    UIImageView *image1;
    UIImageView *image2;
    NSMutableDictionary *isUseable;
}

@property (nonatomic, retain) IBOutlet UIImageView *image1;
@property (nonatomic, retain) IBOutlet UIImageView *image2;
@property (nonatomic, retain) NSMutableDictionary *isUseable;

我的.m文件:

@synthesize image1, image2;
@synthesize isUseable

- (void)viewDidLoad
{
    isUseable = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                 @NO, image1,
                 @NO, image2,nil];
}

-(void)runEvents{
    if(some condition){
        [isUseable setObject:@YES forKey:(id)image1];
    }

    //Use it later:
    if(isUseable[image1]){
        //Do stuff
    }
}

它编译但是当我运行它时,我得到一个未捕获的异常'NSInvalidArgumentException',原因:' - [UIImageView copyWithZone:]:发送到实例的无法识别的选择器。

我猜测问题在于NSDictionary类复制其密钥。有没有办法让字典在这种情况下工作?如果没有,我应该如何设置像我想要的查找?有什么想法/建议吗?

4 个答案:

答案 0 :(得分:4)

是的,问题是NSDictionary中的密钥必须符合NSCopying协议,而UIImage则不符。

一种解决方案是为每个图像提供唯一标记。然后使用图像的标记作为关键字(将其包装在NSNumber中)。

- (void)viewDidLoad {
    isUseable = [ @{ @(image1.tag) : @NO, @(image2.tag) : @NO } mutableCopy];
}

-(void)runEvents {
    if(some condition) {
        [isUseable setObject:@YES forKey:@(image1.tag)];
    }

    //Use it later:
    if(isUseable[@(image1.tag)]) {
        //Do stuff
    }
}

只需添加代码即可查看每个图片的tag属性。

答案 1 :(得分:3)

rmaddy表示非常正确:NSDictionary必须符合NSCopying协议,而UIImage则不符。

我建议使用image.hash作为字典键。它就像UIImage的指纹。

答案 2 :(得分:1)

NSDictionaries中的密钥必须符合NSCopyingUIImageView不符合UIImageView。 您必须找到不同的密钥,或者您可以将NSCopying扩展为符合UIImage。有关如何使用{{1}}。

,请参阅this answer on SO

答案 3 :(得分:0)

从图像中获取原始数据(不是重新渲染的 PNG 或 JPG 表示),然后通过内置的 common-crypto 运行它以获取数据的 SHA256,这将是您的密钥。

其他答案建议使用内置实例属性 .hash,但它很容易发生冲突,而且它们最终经常发生(我们在我们的一个应用程序中遇到了字符串冲突并导致了严重的错误)。< /p>

#include <CommonCrypto/CommonDigest.h>

-(NSString *)keyFromImage:(UIImage *)image {

    NSData *imageData = (__bridge NSData *)CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
    
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256((__bridge const void *)imageData, (CC_LONG)imageData.length, result);
    
    NSMutableString *imageHash = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
    
    for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++) {
        [imageHash appendFormat:@"%02x",result[i]];
    }
    
    return imageHash;

}