Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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 客观C理解是一种阶级_Objective C_Casting_Nsnumber - Fatal编程技术网

Objective c 客观C理解是一种阶级

Objective c 客观C理解是一种阶级,objective-c,casting,nsnumber,Objective C,Casting,Nsnumber,Objective-C和XCode的最新版本(4.4) 我有一个代码片段,我无法理解为什么我能够使用一些行,让我解释一下: // For understanding purpose : (NSMutableArray*)_programStack id l_topItemOnStack = [_programStack lastObject]; if([l_topItemOnStack isKindOfClass:[NSNumber class]]) { return [l_topIt

Objective-C和XCode的最新版本(4.4)

我有一个代码片段,我无法理解为什么我能够使用一些行,让我解释一下:

// For understanding purpose : (NSMutableArray*)_programStack

id l_topItemOnStack = [_programStack lastObject];
if([l_topItemOnStack isKindOfClass:[NSNumber class]])
{
    return [l_topItemOnStack doubleValue];
}
我的问题是:由于我的
l_TopItemsTack
类型为
id
,并且我没有将其转换为
NSNumber
,我如何能够使用
[l_TopItemsTack doubleValue]

我猜我必须先将其强制转换为NSNumber才能访问NSNumber方法


我这里缺少什么?

id
表示任何Objective-C类。它与
NSObject*
不同,因为在这种情况下,如果不先将
-doubleValue
方法强制转换为
NSNumber
,则无法使用该方法

您可以将任何消息发送到
id
nil
也是
id
类型),而无需将其强制转换到特定类。不过,您应该谨慎,因为无法识别的选择器将导致崩溃

编辑:
id
表示:指向未知类的Objective-C对象的指针


如果您想进一步了解
id
void*
NSObject*
之间的区别,您应该阅读以下博文:

编译器只需将对象与翻译可见的选择器相匹配(通过
#import

如果查找要匹配的选择器时出现歧义,或者如果签名不匹配且声明了多个选择器,则可能会抱怨消息。在这种情况下,您必须强制转换对象:

return [(NSNumber*)l_topItemOnStack doubleValue];
或将其分配给新变量:

NSNumber * number = l_topItemOnStack;
return [number doubleValue];
为了消除类型歧义,编译器需要知道正确的选择器签名(例如,它可以正确设置堆栈)


在MRC中,编译器实际上可以“假定”参数和返回类型(默认为
id
)——但这在ARC中是禁止的。

因为Objective-C是一种动态语言,消息名称及其声明只是编译器的提示——实际的消息查找和发送发生在运行时。因此,即使编译器不知道您的对象响应了
doubleValue
消息,它仍然能够调用

return objc_msgSend(l_topItemOnStack, @selector(doubleValue));
像往常一样

此外,编译器会查找包含标头中任何位置声明的所有选择器,并尝试使用实际上下文查找最佳匹配项(此处doubleValue是唯一的名称),它仅在NSNumber上声明,因此编译器假定您的对象确实是NSNumber


如果确实要避免这种情况,请在调用该方法时强制转换该对象,或者最初将其声明为NSNumber。

首先检查topItemOnStack是否为NSNumber的类型,因为NSNumber继承了NSValue

NSValue对象是单个C或Objective-C数据项的简单容器。它可以保存任何标量类型,如int、float和char,以及指针、结构和对象ID

topItemOnStack can now be of any type floatValue, intValue or doubleValue as per our requirement
使用isKindOfClass并不是将topItemOnStack强制转换为NSNumber,而是检查它是否属于NSNumber类型


isKindOfClass表示接收方是给定类的实例还是从该类继承的任何类的实例

Objective-C对象具有捆绑的运行时类型信息(著名的
isa
指针)

您可以向任何对象发送任何消息;如果编译器找不到编译时类型信息来决定对象是否响应选择器(在这种情况下
doubleValue
),编译器将抱怨(警告),但我相信类型
id
,是通用的对象,不受此规则的约束,并且任何在编译时都会发生任何事情(请有更有知识的人确认这一点)


当然,如果id类型的变量指向的对象没有实现相应的方法(即,无法响应发送的消息),将引发异常。在iOS中,这意味着应用程序崩溃(除非相关对象已覆盖此默认行为)。在OS X上,不总是这样(再次,请有更了解情况的人确认这一点。

我知道消息查找发生在运行时,但XCode让我自动完成写入“DoubleValue”,我不明白它是如何提供给我的!谢谢你的回答!@AndyM没问题。这是一个隐藏的细节,非常奇怪(我甚至不认为编译器会做这种不合法的欺骗)。顺便说一句,这可能不是Xcode给你自动完成建议的原因-Xcode不是编译器。我理解你的答案,但那不是我的问题,实际上我想知道为什么我有可能向“doubleValue”发送消息不用将我的topItemOnStack添加到NSNumber。谢谢你的回答。我忘记了“id”的细节。因为我是从语言开始的(你可能猜到:),我会在你的博客上读一读,谢谢你的回答!有趣的indead帖子!谢谢!