简体   繁体   English

使用弱引用时是否可以实现NSFastEnumeration?

[英]Is it possible to implement NSFastEnumeration when using weak references?

I have a collection which maintains weak references to its objects. 我有一个集合,该集合维护对其对象的弱引用。 I'd like it to conform to NSFastEnumeration , but the buffer provided by countByEnumeratingWithState:objects:count: uses unsafe_unretained references. 我希望它符合NSFastEnumeration ,但是countByEnumeratingWithState:objects:count:提供的缓冲区使用unsafe_unretained引用。 That creates a gap during which a returned reference could become invalid but not zeroed. 这就造成了间隙,在此间隙期间,返回的引用可能无效但不会归零。

That's fine in the general case -- if the collection stuffs its (currently valid but weakly-referenced) object into the buffer and returns it, then the caller will presumably create its own strong reference if needed. 在一般情况下,这很好-如果该集合将其(当前有效但弱引用)对象填充到缓冲区中并返回它,则调用者可能会在需要时创建自己的强引用。 But that leaves two problems: 但这留下了两个问题:

(1) I don't see any guarantee that the for(){} iteration construct itself creates a temporary strong reference to the object, so if the contents of the {x} block changes something outside the collection in a way that causes the object to be released, then it'll have a dangling reference. (1)我看不出有任何保证for(){}迭代构造本身会创建对对象的临时强引用,因此,如果{x}块的内容以导致要释放的对象,那么它将有一个悬空的引用。

(2) There's still a small gap while returning from countByEnumeratingWithState: during which activity on another thread could invalidate the reference. (2)从countByEnumeratingWithState:返回时,仍然有一个小间隙countByEnumeratingWithState:在此期间,另一个线程上的活动可能会使引用无效。 My collection isn't meant to be thread-safe, but it would be nice if it could at least safely store references to objects which could be referenced on another thread, as there's really no way to prevent that in any multi-threaded application. 我的集合并不是线程安全的,但是如果它至少可以安全地存储对可以在另一个线程上引用的对象的引用,那将是一个很好的选择,因为在任何多线程应用程序中,实际上都无法阻止这种情况。

You can't return a strong reference directly to the caller. 您不能直接将强引用返回给调用方。 The caller won't release it, and the fast enumeration protocol does not guarantee that you will get a chance to release it yourself when the caller is done. 调用者不会释放它,并且快速枚举协议不能保证在调用者完成操作后您将有机会自己释放它。

Instead you can retain+autorelease the objects before you store them into the buffer. 相反,您可以在将对象存储到缓冲区之前保留+自动释放它们。 That would guarantee the objects stay alive while the caller uses them. 这样可以保证在调用者使用对象时这些对象保持活动状态。 It may hurt the "fast" part of fast enumeration, but you would still get the "convenient syntax" part. 它可能会损害快速枚举的“快速”部分,但您仍将获得“便捷语法”部分。 If you add a nil check after you read the weak variable then you can avoid storing nil pointers into the buffer. 如果在读取弱变量后添加了nil检查,则可以避免将nil指针存储到缓冲区中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM