gpt4 book ai didi

objective-c - NSDictionary 的键值不等于设置的键

转载 作者:行者123 更新时间:2023-12-03 16:50:36 25 4
gpt4 key购买 nike

我正在为 OS X 创建一个图像编辑应用程序。我有以下代码,基本上返回与给定图像关联的窗口,如果尚未为该图像创建窗口,则创建一个窗口:

+(TNRWindow*)windowForImage:(NSImage*)img{
static NSMutableDictionary *imageMapping;
static int uidCounter;
if(!imageMapping){
imageMapping = [NSMutableDictionary dictionary];

}
TNRWindow *window = [imageMapping objectForKey:img];
if(!window){
window = [[TNRWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 720) styleMask:(NSResizableWindowMask|NSTitledWindowMask|NSClosableWindowMask) backing:NSBackingStoreBuffered defer:NO];
[window center];
window.uid = [NSNumber numberWithInt:uidCounter++];
[imageMapping setObject:window forKey:img];
}
return window;

}

我已经看到此方法在使用相同的 NSImage 实例连续调用时返回一个新的不同窗口。我分析了代码并意识到 [imageMapping setObject:window forKey:img]; 没有设置正确的键。当我跨过该行时,它会创建一个键值对,但该键与 img 对象不同。

这是 img 对象:

(lldb) po img
<NSImage 0x600000078fc0 Size={1311.5999999999999, 875} Reps=(
"NSBitmapImageRep 0x6100000ba4c0 Size={1311.5999999999999, 875}
ColorSpace=sRGB IEC61966-2.1 colorspace BPS=16 BPP=48
Pixels=5465x3646 Alpha=NO Planar=NO Format=0
CurrentBacking=<CGImageRef: 0x6180003a31e0> CGImageSource=0x61000016c900"
)>

这是我设置字典条目后的关键:

(lldb) po [[imageMapping keyEnumerator] allObjects]
<__NSArrayM 0x618000255930>(
<NSImage 0x610000279440 Size={1311.5999999999999, 875} Reps=(
"NSBitmapImageRep 0x6180000baca0 Size={1311.5999999999999, 875}
ColorSpace=sRGB IEC61966-2.1 colorspace BPS=16 BPP=48
Pixels=5465x3646 Alpha=NO Planar=NO Format=0
CurrentBacking=<CGImageRef: 0x6180003a31e0> CGImageSource=0x61000016c900"
)>
)

对象本身和 NSBitmapImageRep 不同,但支持的 CGImageRefCGImageSource 是相同的。该对象似乎完全有效,但是当我调用 [imageMapping objectForKey:img]; 时,它返回我 nil 因为图像对象本身不是字典中的键。没有多个线程正在调用此方法。这里到底发生了什么?我该如何纠正这种行为?

最佳答案

NSDictionary 复制键 - 以下文本在整个文档中经常重复:

Each key is copied (using copyWithZone:; keys must conform to the NSCopying protocol), and the copy is added to the new dictionary.

键随后按值进行比较,而不是按身份进行比较。所以不同的地址正是应该发生的。

我敢打赌,NSImage 不会实现 isEqual: 来匹配副本。因此,您需要使用 NSImage 以外的其他内容作为 key 。

如果您只想按身份而不是按值进行比较,则可以通过 +valueWithNonretainedObject: 使用 NSValue

例如

....
NSValue *key = [NSValue valueWithNonretainedObject:img];
TNRWindow *window = [imageMapping objectForKey:key];
if(!window){
...
[imageMapping setObject:window forKey:key];
}

编辑:NSDictionaryCFDictionary 是免费桥接的,您可以为核心基础级别的几乎所有事物指定自定义函数,这将允许您创建一个NSDictionary 保留键而不是复制。这实际上取决于您最快乐的工作级别。

关于objective-c - NSDictionary 的键值不等于设置的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19748801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com