CoreData NSArrayController addObject: Agonizingly Slow
I have a CoreData app that imports information from an *.xml file. The file has two sections, summary and detail.
In essence, I have two table views, tvSummary and tvDetail; two array controllers, acSummary and acDetail; and one mutable array, maDetail.
I use the [acSummary addObject:newSummaryData];
method to add summary data records to the acSummary array controller when I import a file. Once the file is imported the summary data fields populate the tvSummary table view.
When I use the [a开发者_C百科cDetail addObject:newDetailData];
method to add detail data records to the acDetail array controller it can take upwards of twenty minutes to import up to 72000 records (most files contain between 3600 and 21600 records). Once this lengthy process is completed the imported detail data fields populate the tvDetail table view. When I make selections in the tvSummary table view the data displayed in the tvDetail table view changes to match the selected row. I think this is how it is supposed to work.
During the Cocoa / Objective-c / Core Data learning process (I am still a neophyte) I have found I can copy 72000 records to the maDetail mutable array in about five seconds. I have also found I can copy the contents of the maDetail mutable array to the acDetail array controller in about two seconds using the [acDetail setContent:maDetail];
method.
What I can not figure out is how to get the acDetail array controller to remember the content it was given when I select a different row in the tvSummary table view. I see references to forcing an array controller 'save', however, I can not find any documentation on how to implement such a method. Any advice or direction would be greatly appreciated.
NSArrayController is, as the documentation for that class tells us, "a bindings compatible class that manages a collection of objects." Cocoa bindings is like an automatic controller that synchronizes data between model and view objects - each time you modify a bound property, all the objects bound to that property are notified and will update themselves as necessary.
If you're adding 72,000 objects one at a time to a mutable array through a NSArrayController, it's likely that an awful lot of unnecessary notifications are being sent, and a lot of useless updates are being performed. There are several ways that you could address that, but I'd suggest trying the simplest thing first...
Instead of adding each record individually, add all the records to a separate mutable array. When that's done, add all the objects to the managed array at once using NSArrayController's -addObjects:
method. This should notify observers that the array has changed once rather than once per object, and I think you'll see a substantial improvement in performance.
I'd address your concern about saving, but I really don't understand what you're trying to do. Perhaps you could tell us a bit more and restate it as an actual question.
I'm not exactly sure I understand your setup but it looks to me that you are not using the array controllers properly with Core Data. You don't have to add objects directly to the controller if you are using Core Data.
You should be able to add new objects directly to the Core Data object graph (just by inserting them) and have the controllers automatically pickup that they exist. Conversely, the controller should also be aware of deletions or updates.
The controllers will observe the Core Data context and responds to changes in it automatically. That is how binding works and why you can write an entire app with virtually no code.
精彩评论