2017-01-08 31 views
0

我使用NSCollectionView以及Content Array(Legacy)佈局,因此我需要setContent:僅在通過NSLibraryGridItem子類和.xib文件構建集合視圖項目時更改集合視圖項目。但是,我的一些用戶在調用setContent:時收到崩潰,但很少。這是崩潰日誌:執行setContent時有時出現NSInternalInconsistencyException

Crashed Thread: 0 Dispatch queue: com.apple.main-thread 

Exception Type: EXC_CRASH (SIGABRT) 
Exception Codes: 0x0000000000000000, 0x0000000000000000 

Application Specific Information: 
objc[5520]: garbage collection is OFF 
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[NSViewController loadView] could not load the "(null)" nib.' 
*** First throw call stack: 
(
0 CoreFoundation 0x00007fff843b4f56 __exceptionPreprocess 198 
1 libobjc.A.dylib 0x00007fff895bfd5e objc_exception_throw 43 
2 CoreFoundation 0x00007fff843b4d8a [NSException raise:format:arguments:] 106 
3 CoreFoundation 0x00007fff843b4d14 [NSException raise:format:] 116 
4 AppKit 0x00007fff8630b1b5 -[NSViewController loadView] 336 
5 AppKit 0x00007fff86306dfe -[NSViewController view] 41 
6 AppKit 0x00007fff8694c425 -[NSCollectionViewItem _copyConnectionsToItem:] 49 
7 AppKit 0x00007fff8694c9d9 -[NSCollectionViewItem copyWithZone:] 541 
8 CoreFoundation 0x00007fff8435cd54 -[NSObject copy] 20 
9 AppKit 0x00007fff869560c7 -[NSCollectionView newItemForRepresentedObject:] 63 
10 AppKit 0x00007fff8695047a -[NSCollectionView _getItemsToDisplay] 1406 
11 AppKit 0x00007fff869568f4 -[NSCollectionView setContent:] 275 
12 MyApp 0x00000001068a1879 _mh_execute_header 112761 
13 libdispatch.dylib 0x00007fff89486a82 _dispatch_call_block_and_release 18 
14 libdispatch.dylib 0x00007fff894888f2 _dispatch_main_queue_callback_4CF 308 
15 CoreFoundation 0x00007fff84349e7c __CFRunLoopRun 1724 
16 CoreFoundation 0x00007fff84349486 CFRunLoopRunSpecific 230 
17 HIToolbox 0x00007fff89b172bf RunCurrentEventLoopInMode 277 
18 HIToolbox 0x00007fff89b1e56d ReceiveNextEventCommon 355 
19 HIToolbox 0x00007fff89b1e3fa BlockUntilNextEventMatchingListInMode 62 
20 AppKit 0x00007fff861da779 _DPSNextEvent 659 
21 AppKit 0x00007fff861da07d -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] 135 
22 AppKit 0x00007fff861d69b9 -[NSApplication run] 470 
23 AppKit 0x00007fff86452eac NSApplicationMain 867 
24 MyApp 0x0000000106887d38 _mh_execute_header 7480 
25 ??? 0x0000000000000002 0x0 2 
) 

terminate called throwing an exception 
abort() called 

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 
0 libsystem_kernel.dylib 0x00007fff89fdfce2 __pthread_kill 10 
1 libsystem_c.dylib 0x00007fff86e8e7d2 pthread_kill 95 
2 libsystem_c.dylib 0x00007fff86e7fa7a abort 143 
3 libc abi.dylib 0x00007fff8753c7bc abort_message 214 
4 libc abi.dylib 0x00007fff87539fcf default_terminate() 28 
5 libobjc.A.dylib 0x00007fff895c01b9 _objc_terminate 94 
6 libc abi.dylib 0x00007fff8753a001 safe_handler_caller(void (*)()) 11 
7 libc abi.dylib 0x00007fff8753a05c std::terminate() 16 
8 libc abi.dylib 0x00007fff8753b152 __cxa_throw 114 
9 libobjc.A.dylib 0x00007fff895bfe7a objc_exception_throw 327 
10 com.apple.CoreFoundation 0x00007fff843b4d8a [NSException raise:format:arguments:] 106 
11 com.apple.CoreFoundation 0x00007fff843b4d14 [NSException raise:format:] 116 
12 com.apple.AppKit 0x00007fff8630b1b5 -[NSViewController loadView] 336 
13 com.apple.AppKit 0x00007fff86306dfe -[NSViewController view] 41 
14 com.apple.AppKit 0x00007fff8694c425 -[NSCollectionViewItem _copyConnectionsToItem:] 49 
15 com.apple.AppKit 0x00007fff8694c9d9 -[NSCollectionViewItem copyWithZone:] 541 
16 com.apple.CoreFoundation 0x00007fff8435cd54 -[NSObject copy] 20 
17 com.apple.AppKit 0x00007fff869560c7 -[NSCollectionView newItemForRepresentedObject:] 63 
18 com.apple.AppKit 0x00007fff8695047a -[NSCollectionView _getItemsToDisplay] 1406 
19 com.apple.AppKit 0x00007fff869568f4 -[NSCollectionView setContent:] 275 
20 MyApp 0x00000001068a1879 0x106886000 112761 
21 libdispatch.dylib 0x00007fff89486a82 _dispatch_call_block_and_release 18 
22 libdispatch.dylib 0x00007fff894888f2 _dispatch_main_queue_callback_4CF 308 
23 com.apple.CoreFoundation 0x00007fff84349e7c __CFRunLoopRun 1724 
24 com.apple.CoreFoundation 0x00007fff84349486 CFRunLoopRunSpecific 230 
25 com.apple.HIToolbox 0x00007fff89b172bf RunCurrentEventLoopInMode 277 
26 com.apple.HIToolbox 0x00007fff89b1e56d ReceiveNextEventCommon 355 
27 com.apple.HIToolbox 0x00007fff89b1e3fa BlockUntilNextEventMatchingListInMode 62 
28 com.apple.AppKit 0x00007fff861da779 _DPSNextEvent 659 
29 com.apple.AppKit 0x00007fff861da07d -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] 135 
30 com.apple.AppKit 0x00007fff861d69b9 -[NSApplication run] 470 
31 com.apple.AppKit 0x00007fff86452eac NSApplicationMain 867 
32 MyApp 0x0000000106887d38 0x106886000 7480 

與我的應用程序正常工作,並且所收到的崩潰只是做規律性的東西的用戶,這意味着有明顯導致崩潰沒有特殊情況,那我無法重現該錯誤。

重要信息:我的應用需要支持macOS 10.6,所以我只能使用支持該系統的解決方案。

EDIT(30/08/2017):

的問題仍然沒有解決。我做了,爲了避免撞車,但我仍然不知道它的由來:

-(BOOL)safeSetContent:(NSArray*)newContent 
{ 
    @try 
    { 
     [self setContent:newContent]; 
     [self setNeedsDisplay:YES]; 

     return YES; 
    } 
    @catch (NSException* exception) 
    { 
     if (exception.name == NSInternalInconsistencyException) 
     { 
      [NSAlert showAlertOfType:NSAlertTypeError withMessage:@"An unexpected NSInternalInconsistencyException occured."]; 
      return NO; 
     } 

     [NSAlert showAlertMessageWithException:exception]; 
     return NO; 
    } 
} 

它說,我沒有在我的代碼任何部分使用NSViewController很重要(該項目在Mac OS X 10.6時代創建,並且它不是默認的)。

而這些調用safeSetContent:三個功能:

-(void)forceReloadTableContents 
{ 
    NSArray* contentArray = self.appsArray.tabType == DEFAULT_TYPE ? @[DEFAULT_VALUE] : nil; 

    [NSThread dispatchBlockInMainQueue:^ 
    { 
     if ([self safeSetContent:contentArray]) 
     { 
      [NSThread dispatchQueueWithName:THREAD_RELOAD_GRID_VIEW_AFTER_SAVE 
            priority:DISPATCH_QUEUE_PRIORITY_DEFAULT concurrent:NO withBlock:^ 
      { 
       [self reloadTableContents]; 
      }]; 
     } 
    }]; 
} 

-(void)reloadTableWithType:(NSInteger)type 
{ 
    [self safeSetContent:@[]]; 

    if (type == DEFAULT_TYPE) 
    { 
     [NSThread detachNewThreadSelector:@selector(loadDefaultType) toTarget:self.libraryTabView withObject:nil]; 
    } 
    else 
    { 
     [(NSLibraryTabView*)self.libraryTabView loadOtherType]; 
    } 
} 

-(void)reloadTableContents 
{ 
    BOOL isServer = (self.appsArray.tabType == DEFAULT_TYPE); 
    NSMutableArray* contentArray = isServer ? [@[DEFAULT_VALUE] mutableCopy] : [@[] mutableCopy]; 
    if (self.appsArray.array) [contentArray addObjectsFromArray:self.appsArray.array]; 
    if (contentArray.count == 0) contentArray = nil; 

    [NSThread dispatchBlockInMainQueue:^ 
    { 
     if ([self safeSetContent:contentArray]) 
     { 
      [[NSNotificationCenter defaultCenter] postNotificationName:COLLECTION_VIEW_UPDATE_NOTIFICATION object:nil]; 
     } 
    }]; 
} 

我已經改變了一些變量的名稱。

這個bug在10.6到10.12的多個macOS版本中被觀察到。

我想這是我的NSCollectionViewItem子類的相關內容:

@implementation NSLibraryGridItem 

-(NSDictionary*)representedDictionary 
{ 
    if (!self.representedObject) return nil; 

    return (NSDictionary*)[self.representedObject copy]; 
} 
-(void)setRepresentedObject:(id)representedObject 
{ 
    [super setRepresentedObject:representedObject]; 

    NSDictionary* info = self.representedDictionary; 

    if (info) 
    { 
     if ([info isKindOfClass:[NSDictionary class]]) 
     { 
      // App logic 
     } 
    } 
} 

@end 

而且NSLibraryGridItem被選爲與集合視圖awakeFromNib中的觀點:

self.collectionViewItem = [NSLibraryGridItem new]; 
[self setItemPrototype:self.collectionViewItem]; 
+0

下面是所有這些重要的短語:'reason:' - [NSViewController loadView]無法加載「(null)」nib'。另外請注意,在沒有看到代碼的情況下診斷或修復幾乎是不可能的。我會尋找一個集合視圖嘗試獲取視圖控制器視圖的地方。 – danh

+0

我想這也是一個重要的觀點:我的應用程序沒有與視圖控制器相關的代碼。是否有可能xib文件(技術上有一個nib文件)有時無法加載,這是導致問題的原因? – vitormm

+0

我將檢查我能夠顯示的代碼,但我無法顯示太多 – vitormm

回答

1

根據該文件,行爲的NSViewController這會導致它自動加載一個與NSViewController子類同名的xib文件只能記錄在OS X 10.10及更高版本上可靠地工作,而o ñ舊版本它會導致未定義的行爲:

https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/index.html#10_10ViewController

因爲你的目標10.6,您需要手動指定筆尖名。您可以通過爲NSCollectionViewItem子類中的nibName屬性添加覆蓋來完成此操作。這個應該,我認爲,解決你的問題,因爲你得到的異常是抱怨不知道它需要加載的筆尖的名稱,並且因爲「未定義的行爲」當然似乎描述了你的不可重複性問題。

+0

我會嘗試一下,讓它知道它是否有效:) – vitormm

+0

由於某些原因,當使用nibName時,即使它在xib文件中連接,我的NSCollectionViewItem子類中的NSTextField屬性也是零。如果我刪除了nibName覆蓋,它會再次開始工作。 – vitormm

+0

我也有4個'NSImageView',1'NSProgressIndicator'和1'NSButton',但只有'NSTextField'變爲零。 – vitormm