使用NSView实例作为NSDictionary键?

时间:2010-12-05 21:02:24

标签: objective-c cocoa nsdictionary nsview

我正在尝试创建一组半复杂的视图动画(想想NSMatrix形式的动画版本,其中行在添加或删除其他行时滑动),并构建动画I正在做一个小帮手。

在那里,我必须跟踪不同的视图,它们的有序索引,以及与它们的动画相关的一些其他值。

为此,我正在使用NSArray实例来跟踪视图的排序(索引),并且我想使用NSDictionary将视图作为键来跟踪值(值本身在嵌套字典中)。即我希望能够做到这一点,例如(伪代码):

NSMutableDictionary* viewValuesDict = [NSDictionary dictionary];

// Loop thru an ordered NSArray
for( (NSView*) view in viewsArray ) {
    // Get some values we'll need later
    NSDictionary* associatedValues = [view getSomeValues];

    // ...and put them into viewValuesDict...
    [viewValuesDict setObject:associatedValues forKey:view];

    // and then things break because the NSView 'view'
    // doesn't support copyWithZone.... darn
}

问题,我当然不能将NSView实例用作字典键,因为密钥是使用copyWithZone添加的,NSView不是实施

那么,为NSView实例获取唯一键的好方法是什么?我可以想象使用[obj description],因为你得到的内存地址是一个完美的UID,但当然系统必须使用任何类型的NSView子类,它们可能完全返回其他东西,所以这不好

或者我应该完全尝试其他的东西?是否可能有NSDictionary的替代方法,其中只是不复制密钥?因为在这种情况下我真的不需要复制密钥。

4 个答案:

答案 0 :(得分:8)

有时您可能希望使用视图(NSUI)作为字典中的键。我遇到过这种情况。我宁愿使用objc_setAssociatedObject,但这需要Snow Leopard。使用NSValue进行拳击会有效,但如果您需要进行大量的观察,那么指针的持续装箱和拆箱可能会变得单调乏味。

创建NSView => <object>词典有两种选择。

  1. 使用NSMapTable
  2. 使用CFMutableDictionaryRef
  3. NSMapTable是一个10.5中引入的类,它与NSMutableDictionary非常相似,只不过它具有额外的功能,可以使垃圾收集工作得更好。在您的情况下,您可能想要一个带有“弱”键和“强”值的地图表,但请阅读文档以获取所有有趣的详细信息。

    CFMutableDictionaryRef是核心基础的等同于NSDictionary(它们是免费桥接),但它有一些额外的创建选项。您使用CFDictionaryCreateMutable()创建一个,并且需要两个struct参数。一种是定义如何处理字典的键的内存管理(和其他)行为的结构,另一种是用于定义值的行为的struct。您可以使用保留键(而不是复制键)的选项创建CFMutableDictionaryRef,然后保留值。完成此操作后,您可以将CFMutableDictionaryRef转换为NSMutableDictionary并按照您的预期使用它,只需保留密钥而不是复制密钥。

答案 1 :(得分:2)

使用NSMapTable代替NSDictionary(当然,如果您不使用垃圾回收,则必须确保仔细管理对象的生命周期)。 This article对如何使用它有很好的总结。

答案 2 :(得分:1)

正如andyvn22所说,重组!但如果这不切实际:

  • 如果您的目标是针对Snow Leopard,并且这些关联可能会在视图的生命周期内持续存在,请使用objc_setAssociatedObject()
  • 否则,请优先使用[NSValue valueWithNonretainedObject:] -description。 (就像它说的那样,它不会保留对象,但你的数组会这样做。)

答案 3 :(得分:0)

创建词典,使其中一个值为视图;然后重新排列代码,这样你就不需要根据视图查找字典,而是从字典或索引(将字典放入数组)或自己创建的唯一ID开始(将字典放入字典; ID可以像您开始跟踪的每个新视图的连续数字一样简单)。除非您正在做一些非常复杂和动态的事情,否则应该可以避免只需要NSView来查找信息。