4

アップルはARCのリリースノートに文書化されていますが、実際のランタイムとフレームワークでは決して言及されていない2つのメソッドsupportsWeakPointersを挙げています。これはまた、method is in fact ignored in practice.他の方法はですが、これはどこにも記載されていませんが、NSObject.hで次のように宣言されています。ARCで目的のc Objectを弱参照で使用できるかどうかをテストするにはどうすればよいですか?

実行時に allowsWeakReferenceを呼び出そうとすると、どのようもない場合、オブジェクトは、それへの弱参照の形成をサポートしているかどうかを1つのテストすることができ、次のスタックトレースので

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() 

でクラッシュするプログラムを引き起こし

- (BOOL)allowsWeakReference NS_UNAVAILABLE; 
- (BOOL)retainWeakReference NS_UNAVAILABLE; 

メソッドを使用できますか?

+0

回答はあなたがそうでないようです:http://stackoverflow.com/questions/7788108/the-role-of-supportsweakpointers – CRD

答えて

1

これをまとめてハッキングしました。私が必要とするもののために働く。

@implementation NSObject (MAWeakReference) 

static NSSet *weakRefUnavailableClasses = nil; 

+ (void)load { 
    // https://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html 
    weakRefUnavailableClasses = [NSSet setWithObjects: 
           // Classes that don't support zeroing-weak references 
           @"NSATSTypesetter", 
           @"NSColorSpace", 
           @"NSFont", 
           @"NSFontManager", 
           @"NSFontPanel", 
           @"NSImage", 
           @"NSMenuView", 
           @"NSParagraphStyle", 
           @"NSSimpleHorizontalTypesetter", 
           @"NSTableCellView", 
           @"NSTextView", 
           @"NSViewController", 
           @"NSWindow", 
           @"NSWindowController", 
           // In addition 
           @"NSHashTable", 
           @"NSMapTable", 
           @"NSPointerArray", 
           // TODO: need to add all the classes in AV Foundation 
           nil]; 
} 

- (BOOL)ma_supportsWeakPointers { 
    if ([self respondsToSelector:@selector(supportsWeakPointers)]) 
     return [[self performSelector:@selector(supportsWeakPointers)] boolValue]; 

    // NOTE: Also test for overriden implementation of allowsWeakReference in NSObject subclass. 
    // We must use a bit of hackery here because by default NSObject's allowsWeakReference causes 
    // assertion failure and program crash if it is not called by the runtime 
    Method defaultMethod = class_getInstanceMethod([NSObject class], @selector(allowsWeakReference)); 
    Method overridenMethod = class_getInstanceMethod([self class], @selector(allowsWeakReference)); 
    if (overridenMethod != defaultMethod) 
     return [[self performSelector:@selector(allowsWeakReference)] boolValue]; 

    // Make sure we are not one of classes that do not support weak references according to docs 
    for (NSString *className in weakRefUnavailableClasses) 
     if ([self isKindOfClass:NSClassFromString(className)]) 
      return NO; 

    // Finally, all tests pass, by default objects support weak pointers 
    return YES; 
} 

@end 
関連する問題