如何测试Objective-C对象是否可以在ARC下使用弱引用?
苹果提到了两种方法 supportsWeakPointers
记录在 ARC 的发行说明中,但在实际运行时和框架中从未提及。还可以看出,这种方法实际上在实践中被忽略。另一种方法是
allowsWeakReference
,它没有在任何地方记录,但在 NSObject.h
中声明如下。
- (BOOL)allowsWeakReference NS_UNAVAILABLE;
- (BOOL)retainWeakReference NS_UNAVAILABLE;
尝试在运行时调用 allowsWeakReference
会导致程序崩溃并显示以下堆栈跟踪
objc[17337]: Do not call -_isDeallocating.
#0 0x00007fff9900f768 in _objc_trap ()
#1 0x00007fff9900f8aa in _objc_fatal ()
#2 0x00007fff9901bd90 in _objc_rootIsDeallocating ()
#3 0x00007fff97e92ce9 in -[NSObject _isDeallocating] ()
#4 0x00007fff97b5fad5 in -[NSObject(NSObject) allowsWeakReference] ()
#5 0x00007fff97dfe021 in -[NSObject performSelector:] ()
...
...
#11 0x00007fff97a5fd32 in __-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_1 ()
#12 0x00007fff97dafaaa in _CFXNotificationPost ()
#13 0x00007fff97a4bfe7 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#14 0x00007fff8fa0460f in -[NSApplication _postDidFinishNotification] ()
#15 0x00007fff8fa04375 in -[NSApplication _sendFinishLaunchingNotification] ()
#16 0x00007fff8fa0303c in -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] ()
#17 0x00007fff8fa02d9d in -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] ()
#18 0x00007fff97df9591 in -[NSObject performSelector:withObject:withObject:] ()
#19 0x00007fff97a827eb in __-[NSAppleEventManager setEventHandler:andSelector:forEventClass:andEventID:]_block_invoke_1 ()
#20 0x00007fff97a81772 in -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] ()
#21 0x00007fff97a81600 in _NSAppleEventManagerGenericHandler ()
#22 0x00007fff96623c25 in aeDispatchAppleEvent ()
#23 0x00007fff96623b03 in dispatchEventAndSendReply ()
#24 0x00007fff966239f7 in aeProcessAppleEvent ()
#25 0x00007fff92101af9 in AEProcessAppleEvent ()
#26 0x00007fff8fa001a9 in _DPSNextEvent ()
#27 0x00007fff8f9ff861 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#28 0x00007fff8f9fc19d in -[NSApplication run] ()
#29 0x00007fff8fc7ab88 in NSApplicationMain ()
那么,如果这两种方法都无法使用,如何测试对象是否支持对其形成弱引用呢?
Apple mentions two methods supportsWeakPointers
which is documented in the release notes for ARC but never mentioned in the actual runtime and frameworks. It has also be observed that this method is in fact ignored in practice. Another method is allowsWeakReference
, which is not documented anywhere but declared in NSObject.h
as follows.
- (BOOL)allowsWeakReference NS_UNAVAILABLE;
- (BOOL)retainWeakReference NS_UNAVAILABLE;
Trying to call allowsWeakReference
during runtime causes program to crash with the following stack trace
objc[17337]: Do not call -_isDeallocating.
#0 0x00007fff9900f768 in _objc_trap ()
#1 0x00007fff9900f8aa in _objc_fatal ()
#2 0x00007fff9901bd90 in _objc_rootIsDeallocating ()
#3 0x00007fff97e92ce9 in -[NSObject _isDeallocating] ()
#4 0x00007fff97b5fad5 in -[NSObject(NSObject) allowsWeakReference] ()
#5 0x00007fff97dfe021 in -[NSObject performSelector:] ()
...
...
#11 0x00007fff97a5fd32 in __-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_1 ()
#12 0x00007fff97dafaaa in _CFXNotificationPost ()
#13 0x00007fff97a4bfe7 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#14 0x00007fff8fa0460f in -[NSApplication _postDidFinishNotification] ()
#15 0x00007fff8fa04375 in -[NSApplication _sendFinishLaunchingNotification] ()
#16 0x00007fff8fa0303c in -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] ()
#17 0x00007fff8fa02d9d in -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] ()
#18 0x00007fff97df9591 in -[NSObject performSelector:withObject:withObject:] ()
#19 0x00007fff97a827eb in __-[NSAppleEventManager setEventHandler:andSelector:forEventClass:andEventID:]_block_invoke_1 ()
#20 0x00007fff97a81772 in -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] ()
#21 0x00007fff97a81600 in _NSAppleEventManagerGenericHandler ()
#22 0x00007fff96623c25 in aeDispatchAppleEvent ()
#23 0x00007fff96623b03 in dispatchEventAndSendReply ()
#24 0x00007fff966239f7 in aeProcessAppleEvent ()
#25 0x00007fff92101af9 in AEProcessAppleEvent ()
#26 0x00007fff8fa001a9 in _DPSNextEvent ()
#27 0x00007fff8f9ff861 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#28 0x00007fff8f9fc19d in -[NSApplication run] ()
#29 0x00007fff8fc7ab88 in NSApplicationMain ()
So, how can one test whether an object supports the forming of weak reference to it then, if neither method can be used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最终一起破解了这个。适合我需要的东西。
Ended up hacking this together. Works for what I need it for.