获取 NSNumber 的类型
我想获取 NSNumber 实例的类型。
我发现 http://www.cocoadev.com/index.pl?NSNumber this:
NSNumber *myNum = [[NSNumber alloc] initWithBool:TRUE]; if ([[myNum className] isEqualToString:@"NSCFNumber"]) { // process NSNumber as integer } else if ([[myNum className] isEqualToString:@"NSCFBoolean"]) { // process NSNumber as boolean }
好的,但这不起作用,编译器无法识别 [myNum className]。 我正在为 iPhone 进行编译。
I want to get the type of NSNumber instance.
I found out on http://www.cocoadev.com/index.pl?NSNumber this:
NSNumber *myNum = [[NSNumber alloc] initWithBool:TRUE]; if ([[myNum className] isEqualToString:@"NSCFNumber"]) { // process NSNumber as integer } else if ([[myNum className] isEqualToString:@"NSCFBoolean"]) { // process NSNumber as boolean }
Ok, but this doesn't work, the [myNum className] isn't recognized by the compiler.
I'm compiling for iPhone.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
我建议使用
-[NSNumber objCType]
方法。它允许您执行以下操作:
有关类型编码的更多信息,请查看 Objective-C 运行时参考。
I recommend using the
-[NSNumber objCType]
method.It allows you to do:
For more information on type encodings, check out the Objective-C Runtime Reference.
您可以通过这种方式获取类型,无需进行字符串比较:
numberType 将是以下之一:
You can get the type this way, no string comparisons needed:
numberType will then be one of:
如果您想要区分布尔值和其他任何值,您可以利用布尔 NSNumbers 始终返回共享实例的事实:
If all you want is to differentiate between booleans and anything else, you can make use of the fact that boolean NSNumbers always return a shared instance:
NSNumber 明确不保证返回的类型与用于创建它的方法相匹配,因此这样做可能是一个坏主意。
但是,您可能可以这样做(您也可以与 objc_getClass("NSCFNumber") 等进行比较,但这可以说更便携):
NSNumber explicitly doesn't guarantee that the returned type will match the method used to create it, so doing this at all is probably a bad idea.
However, you could probably do something like this (you could also compare to
objc_getClass("NSCFNumber")
etc., but this is arguably more portable):在斯威夫特中:
In Swift:
使用方法
-[NSNumber objCType] method
获取类型。如果类型等于 @encode(BOOL),或者数字本身是 kCFBooleanFalse 或 kCFBooleanTrue,则它是布尔值。
如果不是“c”,那么它就是一个数字。
如果它是“c”,那么似乎是唯一受支持的方法,无需检查私有类名或与未记录的单例进行比较,而是创建一个包含一个元素(数字)的数组,然后使用 NSJSONSerialization 获取字符串表示。最后,检查字符串表示形式是否包含字符串“true”或“false”。以下是检查 NSNumber 是否为 BOOL 的完整代码:
请注意,使用 NSJSONSerialization 速度很慢,并且如果 @NO/@YES 永远停止始终等于 kCFBooleanFalse/kCFBooleanTrue,那么此方法可能不应该在紧密循环中使用。
Use the method
-[NSNumber objCType] method
to get the type.If the type's equal to @encode(BOOL), or the number itself is kCFBooleanFalse, or kCFBooleanTrue, it's a boolean.
If it's anything else but 'c', it's a number.
If it's 'c', what appears to be the only way supported way, without checking against private class names, or comparing against undocumented singletons, is to turn make an array of one element, the number, and then use NSJSONSerialization to get the string representation. Finally, check if the string representation contains the string "true" or "false". Here is the full code for checking if an NSNumber is a BOOL:
Note that using NSJSONSerialization is slow and if @NO/@YES ever stops always equalling kCFBooleanFalse/kCFBooleanTrue, then this method probably shouldn't be used in a tight loop.
编译器警告您并且它不起作用的原因是因为
-[NSObject className]
是在 Mac OS X 上的 NSObject 上的类别中声明的(在 NSScriptClassDescription.h 中),而在 iPhone 上未声明。 (显然,它不支持 AppleScript。)NSStringFromClass([myNum class])
是您应该在所有平台上使用的安全方法。无论如何,-className
很可能被声明为NSStringFromClass()
的简单包装器......The reason the compiler warns you and it doesn't work is because
-[NSObject className]
is declared in a category on NSObject on Mac OS X (in NSScriptClassDescription.h) and not declared on iPhone. (It doesn't support AppleScript, obviously.)NSStringFromClass([myNum class])
is what you should use to be safe across all platforms. Odds are that-className
is declared as a simple wrapper aroundNSStringFromClass()
anyway...这应该是你想要的字符串。
That should ger the string you want.
要检查 NSNumber 是否包含 bool 值,请尝试以下操作:
To check that NSNumber contains a bool value Try this:
objCType
文档指出返回的类型不一定与创建数字对象的方法匹配
其次,将数字类与给定类类型进行比较或假设的其他方法要共享单例的布尔数字实例没有记录的行为。
一种更(但不完全)可靠的方法是依赖 NSJSONSerialization,因为它可以正确识别使用 bool 创建的数字实例并在 json 中输出 true/false。我们可以期望苹果在使用新的 SDK 和不同的架构时能够解决这一问题。下面是代码:
objCType
documentation states thatThe returned type does not necessarily match the method the number object was created with
Secondly, other methods of comparing the class of number to a given class type or assuming boolean number instances to be shared singletons are not documented behaviour.
A more(not completely though) reliable way is to depend on NSJSONSerialisation as it correctly recognises number instances created with bool and outputs true/false in json. This is something we can expect Apple to take care of while moving with new SDKs and on different architectures. Below is the code:
Swift 版本
NSNumber
是 类簇 因此每个底层类型都可以从实例中计算出来。此代码通过创建预期类型的实例,然后将其与未知类型进行比较,避免了对不同 NSNumber 类型进行硬编码。Swift Version
NSNumber
is a class-cluster so each underlying type can be figured from the instance. This code avoids hard-coding the different NSNumber types by creating an instance of the expected type, and then comparing it against the unknown type.检查对象是否为 NSNumber 类型:
if([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")])
{
//NS编号
}
check object is of NSNumber type :
if([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")])
{
//NSNumber
}