«Introduction to Core Data Programming Guide 11 Who Should Read This Document 11 Organization of This Document 11 See Also 13 Technology Overview 14 ...»
[date] My App[2529:4b03] cannot find data for a temporary oid: 0x60797a0 xcrdt:/MCastB1DA09-BE80-FD259A9-oeaa//yls/8B83-454B-4FA09E4F15
an exception in -[NSSQLCore retainedDataForObjectID:withContext:], and the backtrace looks like:
#1 0x9599a6ac in -[NSSQLCore retainedDataForObjectID:withContext:] #2 0x95990238 in -[NSPersistentStoreCoordinator(_NSInternalMethods) _conflictsWithRowCacheForObject:andStore:] #3 0x95990548 in -[NSPersistentStoreCoordinator(_NSInternalMethods) _checkRequestForStore:originalRequest:andOptimisticLocking:] #4 0x9594e8f0 in -[NSPersistentStoreCoordinator(_NSInternalMethods)
#5 0x959617ec in -[NSManagedObjectContext save:] The call to _conflictsWithRowCacheForObject: is comparing the object you're trying to save with its last cached version from the database. Basically, it's checking to see if any other code (thread, process, or just a different managed object context) changed this object out from underneath you.
Core Data does not do this check on newly inserted objects because they could not have existed in any other scope. They haven't been written to the database yet.
Cause: You may have forced a newly inserted object to "lose" its inserted status and then changed or deleted it. This could happen if you passed a temporary object ID to objectWithID:. You may have passed an inserted object to another managed object context.
Remedy: There are a number of possible remedies, depending on what was the root cause:
Do not pass an inserted (not yet saved) object to another context. Only objects that have been saved can ● be passed between contexts.
Do not invoke refreshObject: on a newly-inserted object.
● Do not make a relationship to an object that you never insert into the context.
● Ensure that you use the designated initializer for instances of NSManagedObject.
● Before you save (frame #6 in the stack trace), the context’s updatedObjects and deletedObjects sets should only have members whose object ID returns NO from isTemporaryID.
Debugging Fetching With OS X version 10.4.3 and later, you can use the user default com.apple.CoreData.SQLDebug to log to stderr the actual SQL sent to SQLite. (Note that user default names are case sensitive.) For example, you can
pass the following as an argument to the application:
-com.apple.CoreData.SQLDebug 1 Higher levels of debug numbers produce more information, although using higher numbers is likely to be of diminishing utility.
The information the output provides can be useful when debugging performance problems—in particular it may tell you when Core Data is performing a large number of small fetches (such as when firing faults individually). Like file I/O, executing many small fetches is expensive compared to executing a single large fetch. For examples of how to correct this situation, see “Faulting Behavior” (page 142).
2012-09-19 | Copyright © 2004, 2012 Apple Inc. All Rights Reserved.
Troubleshooting Core Data Managed Object Models Important: Using this information for reverse engineering to facilitate direct access to the SQLite file is not supported. It is exclusively a debugging tool.
As this is for debugging, the exact format of the logging is subject to change without notice. You should not, for example, pipe the output into an analysis tool with the expectation that it will work on all OS versions.
Managed Object Models My application generates the message "+entityForName: could not locate an NSManagedObjectModel" Problem: The error states clearly the issue—the entity description cannot find a managed object model from which to access the entity information.
Cause: The model may not be included in your application resources. You may be trying to access the model before it has been loaded. The reference to the context may be nil.
Remedy: Be sure that the model is included in your application resources and that the corresponding "project target" option in Xcode is selected.
The class method you invoked requires an entity name and context, and it is through the context that the
entity gets the model. Basically, it looks like:
context --- coordinator --- model
In general, when working with Core Data and you have problems like these, you should ensure:
That the managed object context is not nil ● If you are setting the reference to the context in a nib file, make sure the appropriate outlet or binding is set correctly.
If you are managing your own Core Data stack, that the managed object context has an associated ● coordinator (setPersistentStoreCoordinator: after allocating) That the persistent store coordinator has a valid model ● If you are using NSPersistentDocument, then the managed object model is instantiated using the mergedModelFromBundles: method when the document is initialized.
The documentation also gives you enough information on how to debug and hooks for debugging: there are a handful of methods listed in the “Getting and setting the persistence objects” section of the API reference for NSPersistentDocument for either modifying or inspecting the Core Data objects your document is working with. Simply overriding the implementations, calling super, and inspecting the returned values would give you more information about what may (or may not) be occurring.
Bindings Integration Many problems relating to bindings are not specific to Core Data, and are discussed in “Troubleshooting Cocoa Bindings”. This section describes some additional problems that could be caused by the interaction of Core Data and bindings.
Custom relationship set mutator methods are not invoked by an array controller Problem: You have implemented set mutator methods for a relationship as described in “Custom To-Many Relationship Accessor Methods,” and have bound the contentSet binding of an NSArrayController instance to a relationship, but the set mutator methods are not invoked when you add objects to and remove objects from the array controller.
Cause: This is a bug.
Remedy: You can work around this by adding self to the contentSet binding's key path. For example, instead of binding to [Department Object Controller].selection.employees, you would bind to [Department Object Controller].selection.self.employees.
Cannot access contents of an object controller after a nib is loaded Problem: You want to perform an operation with the contents of an object controller (an instance of NSObjectController, NSArrayController, or NSTreeController) after a nib file has been loaded, but the controller's content is nil.
Cause: The controller's fetch is executed as a delayed operation performed after its managed object context is set (by nib loading)—the fetch therefore happens after awakeFromNib and
Remedy: You can execute the fetch “manually” with fetchWithRequest:merge:error:—see “Core Data and Cocoa Bindings” (page 120).
2012-09-19 | Copyright © 2004, 2012 Apple Inc. All Rights Reserved.
Troubleshooting Core Data Bindings Integration Cannot create new objects with array controller Problem: You cannot create new objects using an NSArrayController. For example, when you click the
button assigned to the add: action, you get an error similar to the following:
2005-05-05 12:00:)).000 MyApp *** NSRunLoop ignoring exception 'Failed to create new object' that raised during posting of delayed perform with target 123456
and selector 'invokeWithTarget:'
Cause: In your managed object model, you may have specified a custom class for the entity, but you have not implemented the class.
Remedy: Implement the custom class, or specify that the entity is represented by NSManagedObject.
A table view bound to an array controller doesn't display the contents of a relationship Problem: You have a table view bound to an array controller that you want to display the contents of a
relationship, but nothing is displayed and you get an error similar to the following:
2005-05-27 14:13:39.077 MyApp *** NSRunLoop ignoring exception 'Cannot create NSArray from object _NSFaultingMutableSet: 0x3818f0 () of class _NSFaultingMutableSet - consider using contentSet binding instead of contentArray binding' that raised during posting of
delayed perform with target 385350 and selector 'invokeWithTarget:'
Cause: You bound the controller's contentArray binding to a relationship. Relationships are represented by sets.
Remedy: Bind the controller's contentSet binding to the relationship.
A new object is not added to the relationship of the object currently selected in a table view Problem: You have a table view that displays a collection of instances of an entity. The entity has a relationship to another entity, instances of which are displayed in a second table view. Each table view is managed by an array controller. When you add new instances of the second entity, they are not added to the relationship of the currently-selected instance of the first.
Cause: The two array controllers are not related. There is nothing to tell the second array controller about the first.
Remedy: Bind the second array controller's contentSet binding to the key path that specifies the relationship of the selection in the first array controller. For example, if the first array controller manages the Department entity, and the second the Employee entity, then the contentSet binding of the second array controller should be [Department Controller].selection.employees.
Table view or outline view contents not kept up-to-date when bound to an NSArrayController or NSTreeController object Problem: You have a table view or outline view that displays a collection of instances of an entity. As new instances of the entity are added and removed, the table view is not kept in sync.
Cause: If the controller's content is an array that you manage yourself, then it is possible you are not modifying the array in a way that is key-value observing compliant.
If the controller's content is fetched automatically, then you have probably not set the controller to "Automatically prepare content."
Alternatively, the controller may not be properly configured.
Remedy: If the controller's content is a collection that you manage yourself, then ensure you modify the collection in a way that is key-value observing compliant—see “Troubleshooting Cocoa Bindings”.
If the controller's content is fetched automatically, set the "Automatically prepares content" switch for the controller in the Attributes inspector in Interface Builder (see also automaticallyPreparesContent). Doing so means that the controller tracks inserts into and deletions from its managed object context for its entity.
If neither of these is a factor, check to see that the controller is properly configured (for example, that you have set the entity correctly).
This article describes how you can efficiently import data into a Core Data application and turn the data into managed objects to save to a persistent store. It discusses some of the fundamental Cocoa patterns you should follow, and patterns that are specific to Core Data.
Cocoa Fundamentals In common with many other situations, when you use Core Data to import a data file it is important to remember “normal rules” of Cocoa application development apply. If you import a data file that you have to parse in some way, it is likely you will create a large number of temporary objects. These can take up a lot of memory and lead to paging. Just as you would with a non-Core Data application, you can use local autorelease pool blocks to put a bound on how many additional objects reside in memory. For more about the interaction between Core Data and memory management, see “Reducing Memory Overhead” (page 145).
You should also avoid repeating work unnecessarily. One subtle case lies in creating a predicate containing a variable. If you create the predicate as shown in the following example, you are not only creating a predicate every time through your loop, you are parsing one.
// Loop over employeeIDs.