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