Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用不可复制对象作为NSMutableDictionary的键?_Objective C_Key_Nsmutabledictionary - Fatal编程技术网

Objective c 使用不可复制对象作为NSMutableDictionary的键?

Objective c 使用不可复制对象作为NSMutableDictionary的键?,objective-c,key,nsmutabledictionary,Objective C,Key,Nsmutabledictionary,我试图找出以下代码: 以及 但感觉有些不好。有什么建议吗?你完全正确,这不好 首先,您编码的类型是错误的(它应该是@encode(id),而不是@encode(id*)),但在大多数情况下,这不会造成大问题 更大的问题是,这完全忽略了内存管理。对象将不会被保留或复制。如果其他代码释放了它,它可能会消失,然后您的字典键将是一个指向垃圾的盒装指针,甚至是一个完全不同的对象。这基本上是世界上最先进的 您有两个很好的选择: 您可以将NSCopying添加到类中,也可以创建一个可复制的子类 此选项仅适用

我试图找出以下代码:

以及


但感觉有些不好。有什么建议吗?

你完全正确,这不好

首先,您编码的类型是错误的(它应该是
@encode(id)
,而不是
@encode(id*)
),但在大多数情况下,这不会造成大问题

更大的问题是,这完全忽略了内存管理。对象将不会被保留或复制。如果其他代码释放了它,它可能会消失,然后您的字典键将是一个指向垃圾的盒装指针,甚至是一个完全不同的对象。这基本上是世界上最先进的

您有两个很好的选择:

  • 您可以将NSCopying添加到类中,也可以创建一个可复制的子类

    • 此选项仅适用于可以有意义地复制的对象。这是大多数类,但不一定是所有类(例如,多个对象代表同一个输入流可能不好)
    • 实现复制即使对于有意义的类来说也是一件痛苦的事情——从本质上来说并不困难,但有点烦人
  • 您可以改为使用创建字典。由于核心基础类型不具有通用复制功能,所以CF字典只是默认保留它的键(尽管您可以自定义它的行为,不管您喜欢什么)。但是CFDictionary还与NSDictionary免费连接,这意味着您可以将
    CFDictionaryRef
    转换为
    NSDictionary*
    (或
    NSMutableDictionary*
    )然后将其与任何其他NSDictionary一样处理

    • 这意味着您用作键的对象在字典中时不得更改(至少不能以影响其
      哈希值的方式更改)-确保不会发生这种情况是NSDictionary通常希望复制其键的原因

  • 你完全正确,这不好

    首先,您编码的类型是错误的(它应该是
    @encode(id)
    ,而不是
    @encode(id*)
    ),但在大多数情况下,这不会造成大问题

    更大的问题是,这完全忽略了内存管理。对象将不会被保留或复制。如果其他代码释放了它,它可能会消失,然后您的字典键将是一个指向垃圾的盒装指针,甚至是一个完全不同的对象。这基本上是世界上最先进的

    您有两个很好的选择:

  • 您可以将NSCopying添加到类中,也可以创建一个可复制的子类

    • 此选项仅适用于可以有意义地复制的对象。这是大多数类,但不一定是所有类(例如,多个对象代表同一个输入流可能不好)
    • 实现复制即使对于有意义的类来说也是一件痛苦的事情——从本质上来说并不困难,但有点烦人
  • 您可以改为使用创建字典。由于核心基础类型不具有通用复制功能,所以CF字典只是默认保留它的键(尽管您可以自定义它的行为,不管您喜欢什么)。但是CFDictionary还与NSDictionary免费连接,这意味着您可以将
    CFDictionaryRef
    转换为
    NSDictionary*
    (或
    NSMutableDictionary*
    )然后将其与任何其他NSDictionary一样处理

    • 这意味着您用作键的对象在字典中时不得更改(至少不能以影响其
      哈希值的方式更改)-确保不会发生这种情况是NSDictionary通常希望复制其键的原因

  • 我不能百分之百确定这个解决方案的正确性,但我发布它只是以防万一

    如果您不想使用CFDictionary,也许可以使用以下简单类别:

    @implementation NSMutableDictionary(NonCopyableKeys)
    - (void)setObject:(id)anObject forNonCopyableKey:(id)aKey {
        [self setObject:anObject forKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (id)objectForNonCopyableKey:(id)aKey {
        return [self objectForKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (void)removeObjectForNonCopyableKey:(id)aKey {
        [self removeObjectForKey:[NSValue valueWithPointer:aKey]];
    }
    @end
    
    这是我在网上看到的一个类似方法(找不到原始源代码)的推广,该方法使用NSMutableDictionary来存储带有UITouch键的对象

    与Chuck的答案中相同的限制也适用:用作键的对象的更改不得影响其哈希值,并且在字典中时不得释放该对象

    还要确保不要将
    -(void)setObject:(id)一个对象与noncopyableKey:(id)aKey
    -(id)objectForKey:(id)aKey
    方法混在一起,因为它不起作用(后者将返回
    nil


    这似乎很好,但可能有一些我没有想到的不必要的副作用。如果有人发现此解决方案有任何其他问题或警告,请发表评论。

    我不能100%确定此解决方案的正确性,但我将发布此解决方案以防万一

    如果您不想使用CFDictionary,也许可以使用以下简单类别:

    @implementation NSMutableDictionary(NonCopyableKeys)
    - (void)setObject:(id)anObject forNonCopyableKey:(id)aKey {
        [self setObject:anObject forKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (id)objectForNonCopyableKey:(id)aKey {
        return [self objectForKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (void)removeObjectForNonCopyableKey:(id)aKey {
        [self removeObjectForKey:[NSValue valueWithPointer:aKey]];
    }
    @end
    
    这是我在网上看到的一个类似方法(找不到原始源代码)的推广,该方法使用NSMutableDictionary来存储带有UITouch键的对象

    与Chuck的答案中相同的限制也适用:用作键的对象的更改不得影响其哈希值,并且在字典中时不得释放该对象

    还要确保不要将
    -(void)setObject:(id)一个对象与noncopyableKey:(id)aKey
    -(id)objectForKey:(id)aKey
    方法混在一起,因为它不起作用(后者将返回
    nil


    这似乎很好,但可能有一些我没有想到的不必要的副作用。如果任何人发现此解决方案有任何其他问题或警告,请发表评论。

    供以后参考

    现在我知道还有更多的选择

  • 重写
    NSCopying
    协议中的方法,并返回
    self
    ,而不是复制自身。(如果不使用ARC,则应保留该值)此外,还应确保对象始终为
    -hash
    返回相同的值
    @implementation NSMutableDictionary(NonCopyableKeys)
    - (void)setObject:(id)anObject forNonCopyableKey:(id)aKey {
        [self setObject:anObject forKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (id)objectForNonCopyableKey:(id)aKey {
        return [self objectForKey:[NSValue valueWithPointer:aKey]];
    }
    
    - (void)removeObjectForNonCopyableKey:(id)aKey {
        [self removeObjectForKey:[NSValue valueWithPointer:aKey]];
    }
    @end