1

标题基本概括了所有内容。我想创建一个 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:]: unrecognized selector sent to instance。

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

4

5 回答 5

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属性。

于 2013-02-17T21:39:33.667 回答
3

rmaddy 说的很对:NSDictionary必须符合NSCopying协议UIImage而不符合。

我建议@(image.hash)用作字典键。这就像一个指纹UIImage

于 2013-02-17T22:33:06.590 回答
1

输入的键NSDictionaries必须符合NSCopyingUIImageView不符合。您将不得不找到不同的密钥,或者您可以扩展UIImageView以符合NSCopying. 有关如何使用UIImage.

于 2013-02-17T21:41:20.173 回答
0

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

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

#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;

}
于 2021-05-20T21:12:23.720 回答
0

根据您的对象的管理方式,您可以将其在内存中的地址用作键(这适用于 UIImageView 或 UIImage ,因为关于此问题的一般讨论似乎围绕一个/或展开):

myDictionary[@((intptr_t)myObject)] = myValue;

于 2021-05-20T21:49:58.373 回答