Re: Core Data - Importing using NSOperation - Problems on main thread

2009-12-20 Thread Quincey Morris
On Dec 20, 2009, at 09:16, Nick Banks wrote:

> Yes I did use the [managedObjectContext save:&error], in the same fashion as 
> in some of the examples provided by Apple.  Interestingly, I am using the 
> same mechanism in a completely unrelated project with no problems, and have 
> studied the Core Data documentation for some time.

It sounds like you're Doing It Wrong™. Here's what the Core Data docs have to 
say about multi-threaded access:

"A persistent store coordinator provides to its managed object contexts the 
façade of one virtual store.
For completely concurrent operations you need a different coordinator for each 
thread."

and:

There are three patterns you can adopt to support multi-threading in a Core 
Data application; in order of preference they are:

"• Create a separate managed object context for each thread and share a single 
persistent store coordinator.
If you need to “pass” managed objects between threads, you just pass their 
object IDs.

"If you want to aggregate a number of operations in one context together as if 
a virtual single transaction, you can lock the persistent store coordinator to 
prevent other managed object contexts using the persistent store coordinator 
over the scope of several operations.

"• Create a separate managed object context and persistent store coordinator 
for each thread.
If you need to “pass” managed objects between threads, you just pass their 
object IDs.

"Using a separate persistent store coordinator for each thread allows for 
completely concurrent operations."

[etc]

Deleting objects that are actively being fetched and/or displayed sure sounds 
like a "completely concurrent" operation. Sounds like you need a separate 
persistent store controller for each thread. (And even then you might have to 
deal with concurrency issues in your user interface, but that's a general 
multithreading headache, not Core Data specific.)

> If I delete an object in the import moc (moc2) will that immediately cause 
> the object in moc1 to be deleted also (thus causing problems when referenced 
> by the UI i.e. it will no longer exist) or will this only happen when I call 
> [managedObjectContext save:&error]?

Deletions occur in the persistent store, not in the managed content. When you 
"delete" an object in a MOC, it's merely flagged so that the underlying data is 
removed from the store when the next save occurs. Neither the store nor any 
other MOC knows about the deletion until at least then.

Nothing can "cause the object in moc1 to be deleted" because the objects (the 
in-memory Objective-C objects) aren't deleted at all. Instead they are 
dealloc'ed or finalized when no longer referenced, according to the normal 
memory management rules. However, still-referenced objects that correspond to a 
saved persistent store deletion (the scenario you describe) will presumably 
produce errors if you cause fetching of their properties to be attempted.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Core Data - Importing using NSOperation - Problems on main thread

2009-12-20 Thread Nick Banks
Thanks Greg,

Yes I did use the [managedObjectContext save:&error], in the same fashion as in 
some of the examples provided by Apple.  Interestingly, I am using the same 
mechanism in a completely unrelated project with no problems, and have studied 
the Core Data documentation for some time.

If I delete an object in the import moc (moc2) will that immediately cause the 
object in moc1 to be deleted also (thus causing problems when referenced by the 
UI i.e. it will no longer exist) or will this only happen when I call 
[managedObjectContext save:&error]?

Regards,

Nick

On 20 Dec 2009, at 17:01, Greg Reichow wrote:

> 
>> Hi,
>> 
>> I have an application that persists its data using core data.  
>> 
>> It uses an NSOperation to download new versions of the data asynchronously.  
>> This NSOperation uses its own MOC (moc2) (as opposed to the MOC (moc1) used 
>> in the main thread, which is used by the UI).  Both MOCs share the same 
>> persistent store which, as I understand it, this is the paradigm recommended 
>> by Apple (for using Core with multiple threads).
>> 
>> My problem occurs when the NSOperation is almost complete and deletes all 
>> the old Managed Objects (that have been replaced by the new data) performs a 
>> [managedObjectContext save:&error] with the intent of making the new data 
>> available in the other MOC (moc1).  
>> 
>> The old data is deleted using [managedObjectContext 
>> deleteObject:objectToDelete] after the new data has been added. 
>> 
>> At the same point in time as the update is taking place, the user may be 
>> scrolling through the data in a UITableView (using custom cells populated 
>> with data from managed objects in the main thread MOC moc1)).  The heavy 
>> lifting is performed by a NSFetchedResultsController - using code similar to 
>> that in the Apple CoreDataBooks example
>> 
>> There are a number of problems with this approach  If the user happens to 
>> select the view causing the fetched results controller to be initialised 
>> 
>> i.e.  [self.fetchedResultsController performFetch: &error]
>> 
>> whilst the NSOperation is deleting the old Managed Objects, and attempts to 
>> scroll an exception is thrown in cellForRowAtIndexPath (as the object that 
>> it is referring to has just been deleted)
>> 
>> Problems also occur in the fetched results controller delegate methods, 
>> where the didChangeObject methods gets called with 
>> NSFetchedResultsChangeUpdate instead of NSFetchedResultsChangeDelete if the 
>> user is scrolling up and down the list at the same time (though everything 
>> works if the user is not scrolling).
>> 
>> Any ideas on how I can avoid these problems, or come up with a more elegant 
>> solution?
>> 
> 
> Are you using the contextDidSaveNotification to pass the updates to the main 
> thread MOC?  This has worked for me in the exact same case you describe above.
> 
> In your NSOperation, you register for the contextDidSaveNotification (for 
> your moc2), which calls a method in the NSOperation when it is received that 
> then passes back the notification data to a method on the main thread (using 
> performSelectorOnMainThread).  This keeps both MOC's in sync.  I think this 
> is documented in the Core Data docs.
> 
> Greg

Nick Banks
Managing Director
Synchromation Ltd.
www.synchromation.com

Office: +33 9 62 60 47 88 (FR)
SkypeIn:+44 20 7193 6114 (UK)
iPhone: +33 6 45 44 54 93 (FR)
iPhone: +44 7763 839 430 (UK)

<>

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Core Data - Importing using NSOperation - Problems on main thread

2009-12-20 Thread Greg Reichow

> Hi,
> 
> I have an application that persists its data using core data.  
> 
> It uses an NSOperation to download new versions of the data asynchronously.  
> This NSOperation uses its own MOC (moc2) (as opposed to the MOC (moc1) used 
> in the main thread, which is used by the UI).  Both MOCs share the same 
> persistent store which, as I understand it, this is the paradigm recommended 
> by Apple (for using Core with multiple threads).
> 
> My problem occurs when the NSOperation is almost complete and deletes all the 
> old Managed Objects (that have been replaced by the new data) performs a 
> [managedObjectContext save:&error] with the intent of making the new data 
> available in the other MOC (moc1).  
> 
> The old data is deleted using [managedObjectContext 
> deleteObject:objectToDelete] after the new data has been added. 
> 
> At the same point in time as the update is taking place, the user may be 
> scrolling through the data in a UITableView (using custom cells populated 
> with data from managed objects in the main thread MOC moc1)).  The heavy 
> lifting is performed by a NSFetchedResultsController - using code similar to 
> that in the Apple CoreDataBooks example
> 
> There are a number of problems with this approach  If the user happens to 
> select the view causing the fetched results controller to be initialised 
> 
> i.e.  [self.fetchedResultsController performFetch: &error]
> 
> whilst the NSOperation is deleting the old Managed Objects, and attempts to 
> scroll an exception is thrown in cellForRowAtIndexPath (as the object that it 
> is referring to has just been deleted)
> 
> Problems also occur in the fetched results controller delegate methods, where 
> the didChangeObject methods gets called with NSFetchedResultsChangeUpdate 
> instead of NSFetchedResultsChangeDelete if the user is scrolling up and down 
> the list at the same time (though everything works if the user is not 
> scrolling).
> 
> Any ideas on how I can avoid these problems, or come up with a more elegant 
> solution?
> 

Are you using the contextDidSaveNotification to pass the updates to the main 
thread MOC?  This has worked for me in the exact same case you describe above.

In your NSOperation, you register for the contextDidSaveNotification (for your 
moc2), which calls a method in the NSOperation when it is received that then 
passes back the notification data to a method on the main thread (using 
performSelectorOnMainThread).  This keeps both MOC's in sync.  I think this is 
documented in the Core Data docs.

Greg
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Core Data - Importing using NSOperation - Problems on main thread

2009-12-15 Thread Nick Banks
Hi,

I have an application that persists its data using core data.  

It uses an NSOperation to download new versions of the data asynchronously.  
This NSOperation uses its own MOC (moc2) (as opposed to the MOC (moc1) used in 
the main thread, which is used by the UI).  Both MOCs share the same persistent 
store which, as I understand it, this is the paradigm recommended by Apple (for 
using Core with multiple threads).

My problem occurs when the NSOperation is almost complete and deletes all the 
old Managed Objects (that have been replaced by the new data) performs a 
[managedObjectContext save:&error] with the intent of making the new data 
available in the other MOC (moc1).  

The old data is deleted using [managedObjectContext 
deleteObject:objectToDelete] after the new data has been added. 

At the same point in time as the update is taking place, the user may be 
scrolling through the data in a UITableView (using custom cells populated with 
data from managed objects in the main thread MOC moc1)).  The heavy lifting is 
performed by a NSFetchedResultsController - using code similar to that in the 
Apple CoreDataBooks example

There are a number of problems with this approach  If the user happens to 
select the view causing the fetched results controller to be initialised 

i.e.  [self.fetchedResultsController performFetch: &error]

whilst the NSOperation is deleting the old Managed Objects, and attempts to 
scroll an exception is thrown in cellForRowAtIndexPath (as the object that it 
is referring to has just been deleted)

Problems also occur in the fetched results controller delegate methods, where 
the didChangeObject methods gets called with NSFetchedResultsChangeUpdate 
instead of NSFetchedResultsChangeDelete if the user is scrolling up and down 
the list at the same time (though everything works if the user is not 
scrolling).

Any ideas on how I can avoid these problems, or come up with a more elegant 
solution?

-- NB


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com