不同类型 NSArray 的快速枚举
我有这个问题这里(以及有关SO的其他问题),以及有关Objective-C集合和快速枚举的Apple文档。不清楚的是,如果 NSArray
填充了不同的类型,并且创建了一个循环,如下所示:
for ( NSString *string in myArray )
NSLog( @"%@\n", string );
这里到底发生了什么?循环会跳过任何非 NSString
的内容吗?例如,如果(为了论证)数组中有一个 UIView
,那么当循环遇到该项目时会发生什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你为什么要这么做?我认为这会导致错误和意外行为。如果您的数组填充有不同的元素,请改用:
相同
您在示例中所做的实际上与“只是因为您将
object
转换为(NSString *)
” 并不意味着string
实际上会指向NSString
对象。这样调用NSLog()
会根据- (NSString *)description方法/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/description" rel="noreferrer">NSObject 协议,数组中引用的类可能符合也可能不符合。如果符合,它将打印出来。否则,就会崩溃。Why would you want to do that? I think that would cause buggy and unintended behavior. If your array is populated with different elements, use this instead:
What you are doing in your example is effectively the same as,
Just because you cast
object
as(NSString *)
doesn't meanstring
will actually be pointing to anNSString
object. CallingNSLog()
in this way will call the- (NSString *)description
method according to the NSObject protocol, which the class being referenced inside the array may or may not conform to. If it conforms, it will print that. Otherwise, it will crash.你必须明白 obj-c 中的指针没有类型信息。即使你写了
NSString*
,它也只是一个编译检查。在运行时,一切都只是一个id
。Obj-c 运行时从不检查对象是否属于给定类。你可以毫无问题地将 NSNumber 放入 NSString 指针中。仅当您尝试调用未在对象上定义的方法(发送消息)时,才会出现错误。
快速枚举是如何工作的?它完全相同:
它只是更快,因为它在较低级别上运行。
You have to understand that a pointer in obj-c has no type information. Even if you write
NSString*
, it's only a compilation check. During runtime, everything is just anid
.Obj-c runtime never checks whether objects are of the given class. You can put NSNumbers into NSString pointers without problems. An error appears only when you try to call a method (send a message) which is not defined on the object.
How does fast enumeration work? It's exactly the same as:
It's just faster because it operates on lower level.
我只是尝试了一个简单的例子...这是我的代码。
现在,如果我只是记录该对象,就没有问题了。
NSNumber
实例被转换为NSString
,但这两种方法都响应-description
,所以这不是问题。但是,如果我尝试在
NSString
上记录-length
......它会抛出
NSInvalidArgumentException
因为NSNumber
> 不响应-length
选择器。长话短说,Objective-C 为您提供了很多帮助。不要用它来吊死自己。I just tried a quick example... Here is my code.
Now if I simply log the object, no problem. The
NSNumber
instance is being cast as anNSString
, but both methods respond to-description
, so its not a problem.However, if I attempt to log
-length
onNSString
...... it throws an
NSInvalidArgumentException
becauseNSNumber
doesn't respond to the-length
selector. Long story short, Objective-C gives you a lot of rope. Don't hang yourself with it.有趣的问题。 快速枚举的最通用语法是
我相信,
,通过这样做,您只需将每个对象转换为
NSString
即可。也就是说,我相信上面的内容相当于我在苹果的 快速枚举文档,但您可以查看示例并看看会发生什么。
Interesting question. The most generic syntax for fast enumeration is
I believe that by doing
instead, you are simply casting each object as an
NSString
. That is, I believe the above is equivalent toI could not find precise mention of this in Apple's documentation for Fast Enumeration, but you can check it on an example and see what happens.
由于所有 NSObject 都会响应 isKindOfClass,因此您仍然可以将转换保持在最低限度:
Since all NSObject's respond to isKindOfClass, you could still keep the casting to a minimum: