UIView 作为字典键?
我想要一个从 UIView
映射到其他内容的 NSDictionary
。
但是,由于 UIView 没有实现 NSCopying 协议,因此我无法直接将它们用作字典键。
I want to have a NSDictionary
that maps from UIView
s to something else.
However, since UIViews do not implement the NSCopying
protocol, I can't use them directly as dictionary keys.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用
NSValue
保存指向UIView
的指针,并将其用作键。NSValues
是可复制的。但是,如果视图被销毁,
NSValue
将保存一个垃圾指针。
You can use an
NSValue
holding the pointer to theUIView
and use this as key.NSValues
are copyable. but, if the view is destroyed, the
NSValue
will hold ajunk pointer.
这是实际的代码(基于 luvieere 的答案 和 Yar 的进一步建议):
Here is the actual code (based on the answer by luvieere and further suggestion by Yar):
虽然这并不是它们真正的目的,但您可以使用 关联引用:
您甚至可以将其包装在类中
ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable
*;在这种情况下,您可能希望保留用作键的视图。像这样的东西(未经测试):
*名称可能需要一些修改。
Although this isn't really what they're intended for, you could whip up a functional dictionary-like interface using Associative References:
You could even wrap this up in a class
ThingWhatActsLikeADictionaryButWithKeysThatArentCopyable
*; in that case you might want to retain the views that you use as keys.Something like this (untested):
*The name may need some work.
如果您在 iOS 6 之前不需要支持,NSMapTable(由 neilsbot 建议)可以很好地工作,因为它可以提供枚举器在集合中的键上。这对于所有文本字段通用的代码来说非常方便,例如设置委托或将文本值与 NSUserDefaults 实例双向同步。
in viewDidLoad
in viewWillAppear:
in textField:shouldChangeCharactersInRange:replacementString:
现在我要哭了,因为我在意识到我的 iOS 5.1 目标应用程序无法使用它之前实现了所有这些。 NSMapTable 是在 iOS 6 中引入的。
Provided you don't need to support before iOS 6, NSMapTable (suggested by neilsbot) works well because it can provide an enumerator over the keys in the collection. That's handy for code common to all of the text fields, like setting the delegate or bi-directionally syncing the text values with an NSUserDefaults instance.
in viewDidLoad
in viewWillAppear:
in textField:shouldChangeCharactersInRange:replacementString:
And now I will go cry, because I implemented all of this before realizing that my iOS 5.1-targeted app can't use it. NSMapTable was introduced in iOS 6.
与其存储指向视图的指针并冒垃圾问题的风险,不如为 UIView 提供一个标签并将标签的值存储在字典中。安全得多。
Rather than store a pointer to the view and risk the garbage issue, just give the UIView a tag and store the tag's value in the dictionary. Much safer.
我正在使用 Objective-C++ 提供的 ARC 下的简单解决方案。
MyClass.mm:
在这个例子中,我通过使所有值都必须是viewMap; 对于键也是如此:
UIColor*
来获得更强的类型检查,这就是我所需要的。但是,如果您想允许任何对象作为值,您也可以使用 id 作为值类型,例如:std::mapid __weak, id __strong> viewMap;
您还可以根据需要更改
__strong
和__weak
属性。就我而言,视图已经由我在其中使用的视图控制器保留,因此我认为没有必要使用强指针指向它们。I'm using a simple solution under ARC provided by Objective-C++.
MyClass.mm:
In this example I am getting stronger type checking by making all the values have to be a
UIColor*
which is all I needed this for. But you could also useid
as the value type if you want to allow any object as the value, ex:std::map<UIView* __weak, id __strong> viewMap;
Likewise for keys:id __weak, id __strong> viewMap;
You can also vary the
__strong
and__weak
attributes as needed. In my case, the views are already retained by the view controller that I use this in, so I saw no need to take a strong pointer to them.当您偶尔只需要
UIView
作为键时,这是一个简单的解决方案,我用它来存储UILabel
和UIColor
a simple solution when you just want
UIView
as key occasionally,I use it to storeUILabel
andUIColor