2013-10-08 29 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对象的操作也必须在主线程上。 –