2013-10-08 31 views
5

所以發生了什麼這裏是應用剛剛收到了NSPersistentStoreDidImportUbiquitousContentChangesNotification,我剛纔叫有沒有人知道這是怎麼回事?核心數據/ iCloud的

- (void)storesDidUpdate:(NSNotification*)note { 
    FLOG(@"storesDidUpdate "); 
    [_managedObjectContext mergeChangesFromContextDidSaveNotification:note]; 

    // Refresh user Interface 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"iProjectCoreDataUpdated" 
                 object:self]; 

    [self updateDetails]; 
} 

而現在的應用程序試圖通過簡單地做更新與文本的新副本一個UITextView以下內容:

self.detailText.attributedText = [self.detailItem valueForKey:@"scope"]; 

其中detailItem是在從iCloud接收更新之前檢索到的NSManagedObject。

不知道爲什麼textContainer在抱怨或者抱怨什麼,也不知道爲什麼導入日誌正在發生,因爲我已經收到一個通知,說它已經完成了!

奇怪的是,其他UITableViews更新正確,如果我只是調用reloadData。

有關我在這裏做錯事情的任何想法?請注意,如果我不嘗試更新textView,它會正常工作,如果我關閉視圖並返回它,那麼我會得到正確的數據。

此外,當我重新啓動應用程序時,所有數據都存在,沒有損壞或任何事情,事實上,儘管事情在iCloud的任何一方都爆炸,但應用程序在覈心數據存儲方面似乎非常健壯。

哦,reloadFetchedResults有點讓人誤解,因爲我似乎不需要這樣做,所以方法名稱是過去的宿醉,我所做的只是刷新UI調用中的值。

2013-10-09 07:25:53.783 MyApp[4509:510b] OpeningViewController.reloadFetchedResults: called 2013-10-09 07:25:53.786 MyApp[4509:510b] InfoDetailViewController.reloadFetchedResults: called in InfoDetailViewController 2013-10-09 07:25:53.788 MyApp[4509:510b] * Assertion failure in void _UIPerformResizeOfTextViewForTextContainer(NSLayoutManager *, UIView *, NSTextContainer *, NSUInteger)(), /SourceCache/UIFoundation/UIFoundation-258/UIFoundation/TextSystem/NSLayoutManager_Private.m:1510 2013-10-09 07:25:53.793 MyApp[4509:510b] -_PFUbiquityRecordImportOperation main: CoreData: Ubiquity: Error importing transaction log: transactionLogLocation: : /var/mobile/Library/Mobile Documents/HHHHHHNNNN~com~mycompany~MyApp/CoreData/New Document/duncangroenewald~simAABC628E-9D5E-58F7-9B8D-0BC724C6D0C8/New Document/W8MckEJ0x2d~HZZIeUH2be6hs41TEOONzKIrCuLcuP4=/6C953E7C-B2AF-47F7-B828-DD062B96415D.1.cdt transactionNumber: 5 , exception: Only run on the main thread! User Info: (null) 2013-10-09 07:25:53.803 MyApp[4509:510b] -_PFUbiquityRecordsImporter operation:failedWithError:: CoreData: Ubiquity: Import operation encountered an error: Error Domain=NSCocoaErrorDomain Code=134060 "The operation couldn’t be completed. (Cocoa error 134060.)" UserInfo=0x16d882c0 {exception=Only run on the main thread!} userInfo: { exception = "Only run on the main thread!"; }. While trying to import the log file at the URL: transactionLogLocation: : /var/mobile/Library/Mobile Documents/HHHHHHNNNN~com~mycompany~MyApp/CoreData/New Document/duncangroenewald~simAABC628E-9D5E-58F7-9B8D-0BC724C6D0C8/New Document/W8MckEJ0x2d~HZZIeUH2be6hs41TEOONzKIrCuLcuP4=/6C953E7C-B2AF-47F7-B828-DD062B96415D.1.cdt transactionNumber: 5 2013-10-09 07:25:53.809 MyApp[4509:510b] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!' *** First throw call stack: (0x2ff23f53 0x3a6996af 0x2ff23e2d 0x308cb1df 0x3796643d 0x37966185 0x3798f7bb 0x379926f7 0x37992759 0x379b378b 0x379b331f 0x379b2f0d 0x3273b05d 0x129717 0x2fee6121 0x2fe5a317 0x3083edcd 0x308436ab 0x118263 0x2fee6121 0x2fe5a317 0x2fd8c69f 0x2fd8cc93 0x2fd813dd 0x3085197b 0x308f5b35 0x3ab83297 0x3ab8309b 0x3ab83d15 0x3ab83f8d 0x3acbedbf 0x3acbec84) libc++abi.dylib: terminating with uncaught exception of type NSException

編輯: 我已經發布了iOS和OSX一些樣本核心數據/ iCloud的應用程序在這裏 - 它們包括用於加載/後臺線程刪除數據,以及iCloud的同步。希望解決這裏描述的問題。 http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/

+0

在其他視圖奇怪的是,完全相同的代碼似乎更新用戶界面沒有任何問題。 –

+0

很難確定,但錯誤信息反覆說'只在主線上運行!'這個事實可能是一個巨大的,巨大的,重要的線索,需要立即認真考慮。 –

+0

Tom看到下面的附加信息... –

回答

8

確定這裏似乎是解決它 - 我想我從來沒有意識到接收通知將運行在另一個線程。這是否是正常行爲,是否所有核心數據通知都會在後臺線程中調用?如果是這樣,你總是必須確保你所做的任何事情都是在正確的線程上運行的?

- (void)storesDidUpdate:(NSNotification*)note { 
    FLOG(@"storesDidUpdate "); 
    [_managedObjectContext mergeChangesFromContextDidSaveNotification:note]; 

    [[NSOperationQueue mainQueue] addOperationWithBlock:^ { 
     //Your code goes in here 
     LOG(@" Main Thread Code"); 

     // Refresh user Interface 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"CoreDataUpdatedNotification" 
                 object:self]; 
    }]; 

} 

編輯:

我終於得到了各地的記錄我是如何得到核心數據和iCloud中,以漂亮的可靠地工作,包括搬運移動,並從iCloud中響應利用改變其使用的iCloud偏好設置。當我試圖弄清楚如何讓它工作時,我無法找到有效的工作代碼的解釋,所以我希望這對其他人有用。包括應用程序的視頻工作,以便您可以看到它的行爲,以幫助您找出是否是您想要實現的。

http://ossh.com.au/design-and-technology/software-development/

+0

哦,我還應該在主線程上調用mergeChangesFromContext ...嗎? –

+0

在發佈它們的線程上收到通知。對於大多數核心數據通知,這意味着您正在使用的任何線程。使用iCloud並不一定如此。 –

+0

糟糕!謝謝湯姆,現在這一切似乎都相當穩定。我仍然試圖打破數據庫,但儘管其他人說Core Data和iCloud是不可靠的,但仍然無法完成。它是可靠的還是我只是沒有足夠的努力。 –

0

是的,我明白了,但我沒有在任何線程上做任何事情,所以別的東西一定是。我正在更新一個UITextView,我猜想它可能會導致一個失敗。我不清楚爲什麼這與這個無處不在的進口商有什麼關係 - 也許有人能夠解釋下面的這些東西可以指引我正確的方向。我以某種方式在錯誤的線程上運行某些東西?

*** First throw call stack: ( 0 CoreFoundation 0x027c55e4 exceptionPreprocess + 180 1 libobjc.A.dylib 0x019238b6 objc_exception_throw + 44 2 CoreFoundation 0x027c5448 +[NSException raise:format:arguments:] + 136 3 Foundation 0x01062960 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 101 4 UIFoundation 0x01b33131 -[NSLayoutManager(NSPrivate) _resizeTextViewForTextContainer:] + 419 5 UIFoundation 0x01b32e16 -[NSLayoutManager(NSPrivate) _recalculateUsageForTextContainerAtIndex:] + 2083 6 UIFoundation 0x01b67675 _enableTextViewResizing + 234 7 UIFoundation 0x01b6b275 -[NSLayoutManager textStorage:edited:range:changeInLength:invalidatedRange:] + 688 8 UIFoundation 0x01b6b2fa -[NSLayoutManager processEditingForTextStorage:edited:range:changeInLength:invalidatedRange:] + 82 9 UIFoundation 0x01b93d35 -[NSTextStorage _notifyEdited:range:changeInLength:invalidatedRange:] + 153 10 UIFoundation 0x01b93870 -[NSTextStorage processEditing] + 462 11 UIFoundation 0x01b93419 -[NSTextStorage endEditing] + 80 12 UIFoundation 0x01b934a3 -[NSTextStorage coordinateEditing:] + 66 13 UIKit 0x007f4f48 -[UITextView setAttributedText:] + 254 14 MyApp 0x00027d7a -[WBSDetailViewController displayItem] + 3146 15 MyApp 0x00028c6c -[WBSDetailViewController refreshUI:] + 156 16 Foundation 0x01088e39 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40 17 CoreFoundation 0x02821524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 20 18 CoreFoundation 0x0277907b _CFXNotificationPost + 2859 19 Foundation 0x00fc2b91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98 20 Foundation 0x00fd206a -[NSNotificationCenter postNotificationName:object:] + 55 21 MyApp 0x00031095 -[BaseAppDelegate storesDidUpdate:] + 293 22 Foundation 0x01088e39 57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40 23 CoreFoundation 0x02821524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 20 24 CoreFoundation 0x0277907b _CFXNotificationPost + 2859 25 Foundation 0x00fddd7b -[NSNotificationCenter postNotification:] + 121 26 CoreData 0x0173c5f4 -[_PFUbiquityRecordsImporter postImportNotificationForStoreName:andLocalPeerID:withUserInfo:] + 1892 27 CoreData 0x0173cbc2 -[_PFUbiquityRecordsImporter operationDidFinish:] + 706 28 CoreData 0x0172e8ce -[_PFUbiquityRecordImportOperation main] + 15102 29 Foundation 0x0108aa69 -[__NSOperationInternal _start:] + 671 30 Foundation 0x01007798 -[NSOperation start] + 83 31 Foundation 0x0108cd34 __NSOQSchedule_f + 62 32 libdispatch.dylib 0x05b794b0 _dispatch_client_callout + 14 33 libdispatch.dylib 0x05b67088 _dispatch_queue_drain + 450 34 libdispatch.dylib 0x05b66e85 _dispatch_queue_invoke + 126 35 libdispatch.dylib 0x05b67e25 _dispatch_root_queue_drain + 83 36 libdispatch.dylib 0x05b6813d _dispatch_worker_thread2 + 39 37 libsystem_pthread.dylib 0x05f05dab _pthread_wqthread + 336 38 libsystem_pthread.dylib 0x05f09cce start_wqthread + 30 ) libc++abi.dylib: terminating with uncaught exception of type NSException

+0

當你遇到崩潰時,請注意Xcode中左側窗格中試圖調用方法的線程。如果它不是com.apple.main-thread,你將不得不在主隊列中使用GCD調用你的代碼。 –

3

我得到了同樣的問題。正是這個問題@John Rogers解釋道。 我創建了UITextViews,並在後臺調用了一個URL來獲取一些數據,這些數據應該插入到我生成的UITextView中。但問題是方法sendAsynchronousRequest將在後臺調用,並導致崩潰在我的情況。

我可以通過在接收我的數據時在主線程上執行特定的選擇器來解決問題。因此,也許你可以將你的方法調用到另一個方法,並調用它是這樣的:

[self performSelectorOnMainThread:@selector(received:) 
         withObject:data 
        waitUntilDone:YES]; 

這樣你回到主線程一次。

0

閱讀所有的答案+評論(和你的修復) - 我認爲應該指出,你必須從主線程更新任何UI控件。

我假設[self updateDetails];調用self.detailText.attributedText = [self.detailItem valueForKey:@"scope"];代碼?...這是更新UI的實際代碼?

假設您可以使用-performSelectorOnMainThread或-updateDetails檢查您在主線程([NSThread isMainThread])上執行的代碼,並在其中包裝UI更新代碼,以便調用者不會執行對-updateDetails的調用關心他們稱之爲「更新細節」的線程。

+0

正如你可以在我的答案中看到的,我總是從主線程發佈我的通知,所以任何UI更新代碼總是在主線程上調用。我不再使用我發佈的初始代碼。現在,每個UIViewController都會偵聽我的通知,該通知發佈在主線程上,然後調用一個方法 - (void)displayDetails {},其中包含UI更新代碼,例如上面的代碼提取。 –

+0

是的,您應該能夠包裝更新代碼,以便它始終在主線程上執行。但是,我不這樣做,因爲它不只是UI更新必須在主線程上,任何主要managedObjectContext對象的操作也必須在主線程上。 –