键值编码及其脚本能力
我有一个直接实例变量的对象。 有些是 NSString,有些是无符号整数,等等。我的印象是键值编码是可脚本化的,因为我可以编写如下代码:
id key, value;
key = [[attributes objectAtIndex:j] name];
value = [[attributes objectAtIndex:j] stringValue];
[obj setValue:value forKey:key];
我在这里使用 stringValue 和 name 的原因是我正在使用 TouchXML以及从 XML feed 构建对象。
如果我尝试将任何内容分配给整数,上面的代码就会崩溃。 如果我将 unsigned int 更改为 NSString 的实例,则不会出现任何运行时崩溃。 据我了解,键值编码足够智能来检测这些问题。
我可能的解决方案是什么? 我如何尽可能地抽象它,以便我可以在许多不同的类上运行相同的方法,这些类都有自己的实例变量?
真正重写我的 setter 并使用 NSNumber 将字符串转换为 int 类型(我认为已经由 KVC 处理)的最优雅的方法是吗?
I have an object which straight forward instance variables. Some are NSString, some are unsigned ints, etc. I was under the impression Key-Value coding was scriptable in that I could write code such as the following:
id key, value;
key = [[attributes objectAtIndex:j] name];
value = [[attributes objectAtIndex:j] stringValue];
[obj setValue:value forKey:key];
The reason I'm using stringValue here and name is I'm working with TouchXML and building objects from XML feeds.
The code above crashes if I try to assign anything to an integer. If I change my unsigned int to an instance of NSString, there isn't any run-time crashes. It was to my understanding that Key-Value coding is smart enough to detect these issue.
What are my possible solutions? How can I abstract this as much as possible so I can run the same method on many different classes which all have their own instance variables?
Is the most elegant method to really override my setter and use NSNumber to convert the string into a type int, which I thought was already handled by KVC?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
KVC 不会在内部进行任何类型强制/转换,因此您传递给
setValue:forKey:
的对象类型必须与其将存储在其中的实例变量的类型相匹配。本机类型,例如int
、long
等被打包成NSNumber
对象,结构体之类的东西被打包成NSValue
对象。 要设置声明为本机类型的值,您应该为值参数传递适当的包装对象。我还建议在调用 setter 的代码中进行任何所需的翻译,而不是在 setter 本身中。 但这更多是一个意见问题,所以我想如果你真的愿意的话,你可以在设置器中翻译内容。 我的代码版本看起来像这样:
KVC doesn't do any type coercion/translation internally, so the type of the object you pass into
setValue:forKey:
must match the type of the instance variable it will be stored in. Native types such asint
,long
, etc. are packaged up intoNSNumber
objects, and things like structs get packed intoNSValue
objects. To set a value that's declared as a native type, you should pass an appropriate wrapper object in for the value argument.I would also recommend doing any required translation in the code that's calling the setter, and not in the setter itself. That's more a matter of opinion though, so I suppose you could translate stuff in the setter if you really want to. My version of your code would look something like: