0

Should the same UIManagedDocument be open on both of my devices, and I save (using the following code):

[self.documentDatabase.managedObjectContext performBlockAndWait:^{
    STNoteLabelCell *cell = (STNoteLabelCell *)[self.noteTableView cellForRowAtIndexPath:indexPath];

    [cell setNote:newNote animated:YES];
}];

I am told that the UIManagedDocuments documentState is changed to UIDocumentStateSavingError then I get this error:

CoreData: error: (1) I/O error for database at /var/mobile/Applications/some-long-id/Documents/Read.dox/StoreContent.nosync/persistentStore.  SQLite error code:1, 'cannot rollback - no transaction is active'
2013-05-14 16:30:09.062 myApp[11711:4d23] -[_PFUbiquityRecordImportOperation main](312): CoreData: Ubiquity:  Threw trying to get the knowledge vector from the store: <NSSQLCore: 0x1e9e2680> (URL: file://localhost/var/mobile/Applications/some-long-id/Documents/Read.dox/StoreContent.nosync/persistentStore)

Does anybody know why this error happens?

Adam Carter
  • 4,741
  • 5
  • 42
  • 103

1 Answers1

0

A couple of things...

I think the saving the same document on two different devices is a red herring, as it will actually be working on a local copy of your database on each device - only the transaction logs get uploaded to iCloud.

Secondly, I may be confused, but I don't see anything in the above code snippet that indicates you are performing a save (unless it is triggered by one of those calls, or autosave happens).

What that code snippet does seem to be doing is:

  • On your database document's child MOC thread, run the following block of code
  • And that block of code is doing purely UI related stuff, nothing to actually do with the database? The only thing that might be going out to the DB is cellForRowAtIndexPath - and this usually would be expected to only be doing read operations, not something that needs to save.

The only other thing.... if the above code does trigger a save - you might have an issue with performing that as a performBlockAndWait. The UIManagedDocument save routines do stuff asynchronously - but they need the run loop to execute before they actually get a chance to run the async part... So by blocking before continuing you may actually be preventing the actual save from being executed or something.

I'm guessing wildly here, but have seen enough with saving managed documents to know to be really careful with which thread things are actually being called from, and that after a save request has been made, to allow the run loop to have a chance to actually do it. To be fair, this has only ever been an issue with calling saveToURL: repeatedly within one method, or in a loop, in which case all the async parts of the saves get queued up and executed at the end, usually to great comical effect.

Rob Glassey
  • 2,237
  • 20
  • 21