Core Data: Error if deleting unsaved object - objective-c

I have some trouble with a core data project. I have a NSArrayController with NSManagedObjects in it, and + / - buttons. If i delete a object in the row after the file has been saved it works perfectly, but if I add a new object, and immediately delete it again (without changing any of the default values), i get an error:
Serious application error. Exception was caught during Core Data change processing: Unknown number type or nil passed to arithmetic function expression. with userInfo (null)
Unknown number type or nil passed to arithmetic function expression.
It's the same case if i undo the add of the new object.
Anybody able to give me a pointer what to do? I assume it has something to do with that it only has an temporary ID, but how to solve it i don't know.

I found the problem and solution. For the record i will describe it.
The problem was that the object in its init function added an observer on itself. This was probably what triggered the error. If i before i delete the object remove itself as observer, the error is not produced.

Tables don't usually contain NSManagedObjects. Rather, either an NSArrayController is providing the managed objects' attributes as values via bindings or an object conforming NSTableViewDataSource is. The deletion of a selected object provided in either of these scenarios can be done a myriad of ways. The problem is, you haven't explained at all how your case is set up.
Is it possible your deletion (whatever target/action your button is wired to) is being passed nil or something unexpected? I can imagine a similarly-frighenting error if you asked a managed object context to delete a float value or some other random thing ...

Related

What error should I return when a COM object has been deleted but is being attempted to be referenced?

I have extended an API in C++ written on a legacy framework that is used via JavaScript/VB. There is an object that can create from another object. However, the coder can hold on to that object (it's exposed) and do operations on it. Also, the object can be deleted. Because of that last part, I need to keep the object around, even when it is deleted in case the developer tries to reference through that object, and if they attempt to do so, return an error (HRESULT), otherwise, it could cause a crash.
What is the best common HRESULT that I should use? I can't seem to find one that matches what I want.
The only one that I found the winerr.h file that might be relivant is ERROR_FLT_DELETING_OBJECT, but I don't think it is meant for that.
EDIT
Perhaps I should not use the word delete and replace it with instead detach. The object is to be detached from the main object, but is still lives on till the gc cleans up. However, if the user were to attempt to use this detached object, I want them to wake up to the fact that they have already detached it and that they shouldn't be playing with it any more.
EXAMPLE
var newObj = container.create_newObject();
newObj.doStuff();
container.doStuffWithNewObject(newObject);
container.RemoveObject(newObj);
newObj.doStuff(); // ERROR - see, still have reference and attempting to do stuff.
container.doStuffWithNewObject(newObject); // ERROR

Passing an ADO SQL connection ByVal

I have an existing application written in Visual Basic. It's a web application build on ASP.NET and WCF that we use for reporting.
The result is a page that refreshes it's data every set amount of time. Usually after a day or so, this particular page crashes and the service must be reset, however other pages work. My working theory has to do with connections.
Connections to SQL Server are made through the class SQLDataAccess. This class creates a new connection when it is instantiated, the connection can be closed by calling a method on the class.
Most calls look like this:
Try
existingConnection.DataRequest.CommandText = "dbo.p_Select_Table"
DataAccessConnection.ExecuteDataSet()
Catch
Finally
If(existingConnection IsNot Nothign) Then
existingConnection.closeConnection()
End If
End Try
However two connections are initially made, then both connections are passed around more than this bug report was. They get passed ByVal.
Will this create new connections and neglect to close the old one?
When you pass any reference type by value, what you are passing is a reference. No object is copied. Passing a method parameter by value is basically just the same as assigning one variable to another. If the type is a value type then the object is copied and both variables contain different objects. For reference types, both variables refer to the same object. It's just like objects in the real world. If I lend you my car, does that mean there are two cars? No it doesn't, and it's the same when you pass a reference type object by value.

The optimal way to determine if NSManagedObject related attribute object exist

I got a log object retrieved by NSFetchedResultsController, it has an optional attribute that's an slide object. And it's currently faulted. So if I log log.slide, it will return a faulted object. How do I check if log actually have a slide object attached to it? I want to be able to use if(log.slide){...}
I tried to set the NSFetchRequest to [request setReturnsObjectsAsFaults:NO]; before hand it to NSFetchedResultsController. But it's still returning faulted objects. Thanks!
A fault is automatically fulfilled when you access it, so you can simply use your example if (log.slide) {...} and it will work like you expect it to, fulfilling the fault if necessary.

NSManagedObject changed properties after save

Is it possible to find out which properties were saved on a managed object after the save occurs? For example, I have someone listening for managed object context saves, (NSManagedObjectContextDidSaveNotification) and I want to know which properties on the objects were saved.
The NSManagedObjectContextDidSaveNotification does contain all three bits of information you would need to sync with a server. Check the [notification userInfo] and you will find three sets inside: NSInsertedObjectsKey, NSUpdatedObjectsKey, and NSDeletedObjectsKey
If you want to know what properties on an entity have changed that would require that you track them yourself using KVO. I would recommend against this as the odds of that level of effort being worth it over just pushing the entire object up to a server are slim.
Update #2
On further poking around:
From the NSManagedObjectContextWillSaveNotification you could loop through each set and reference the changedValues method. You could keep a reference to that dictionary until after you receive the NSManagedObjectContextDidSaveNotification and then process the changes. Still sounds very heavy to me.
Update
What is your end goal?!?!
If you are trying to figure out what to push to a server then being at the attribute level is too low. You should be syncing at the entity level.
If you are just trying to keep some internal consistency inside of your application then you are thinking way, way too low level. This is a solved problem. Core Data solved it.
Why don't you get them when they are about to be saved. Subscribe to NSManagedObjectContextWillSaveNotification and check insertedObjects, updatedObjects and deletedObjects of the NSManagedObjectContext.
Update:
Even easier, get the user info of the NSManagedObjectContextDidSaveNotification
From the documentation:
Typically, on thread A you register for the managed object context
save notification, NSManagedObjectContextDidSaveNotification. When you
receive the notification, its user info dictionary contains arrays
with the managed objects that were inserted, deleted, and updated on
thread B.
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385-SW1
Here's the solution I settled with. I have one singleton class that is notified when a context saves. The NSManagedObjectContextWillSave notification tells me which things have changed so I store them in a dictionary with the key being the context that saved. Then when I get the NSManagedObjectContextDidSave notification, I check the dictionary for the associated context. Finally, I remove that entry from the dictionary. Does that seem reasonable?

NSManagedObject Faulted

I have an NSManagedObject that has some of its properties initialized at the start of the program. When I refer to this object later, it appears to be faulted, and the properties are not accessible. I'm not sure what I need to do.
This is related to a new feature added to a program that has been operating smoothly with core-data in all other ways.
Here is a code snippet where it is initialized as a property value of a singleton. (That singleton is accessible by many parts of my code):
favoritesCollection = [[SearchTerms alloc] initWithEntity:[NSEntityDescription entityForName:#"SearchTerms" inManagedObjectContext:moc] insertIntoManagedObjectContext:moc];
favoritesCollection.keywords = #"Favorites List";
favoritesCollection.isFavoritesCollection = [NSNumber numberWithBool:YES];
favoritesCollection.dateOfSearch = [NSDate NSCExtendedDateWithNaturalLanguageString:#"4000"];
favoritesCollection.pinColorIndex = 0;
[moc save:&error];
NSLog(#"(favoritesCollection) = %#", favoritesCollection);
}
return favoritesCollection;
When I look at favoritesCollection with the NSLog, I see this (I added some newlines to make it easier to read):
(favoritesCollection) =
<SearchTerms: 0x5c28820>
(entity: SearchTerms; id: 0x5a6df90
<x-coredata://3936E19F-C0D0-4587-95B6-AA420F75BF78/SearchTerms/p33> ;
data: {
dateOfSearch = "4000-09-25 12:00:00 -0800";...*more things after this*
After the return, another NSLog shows that contents are intact.
When I refer to this instance later, I can see this in the debugger:
<SearchTerms: 0x5c28820>
(entity: SearchTerms; id: 0x5a6df90
<x-coredata://3936E19F-C0D0-4587-95B6-AA420F75BF78/SearchTerms/p33> ;
data: <fault>)
and that's all.
So I believe that the object is retained (I explicitly retain it where it is returned). I have zombies on and it doesn't look like a zombie.
I have only one managedObjectContext in the program, maintained in the singleton.
So what is happening, and how do I get to the properties that were saved?
There is nothing wrong with your object and I think you might be misinterpreting the meaning of "fault" here.
From Apple's documentation:
"Faulting is a mechanism Core Data employs to reduce your
application’s memory usage..."
Once you try and access any of the object's properties it will hit the database for all of the object's properties.
More details here http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html
Faults are CoreData's way of having loose links to other entities. Just access the values via properties or valueGorKey and you will see them populated just in time.
I'm a little late getting back to this, but I found out that some steps in my program were out of order. Instead of deleting the database contents (something I do at startup every time, for now) and then creating and adding this entity, I had created and added the entity and then deleted the database contents.
The pointer to the favoritesCollection entity is held for the lifetime of the program, so I would have expected it be able to see its contents any time after it was created.
From the Core Data Programming Guide
Fault handling is transparent—you do not have to execute a fetch to
realize a fault. If at some stage a persistent property of a fault
object is accessed, then Core Data automatically retrieves the data
for the object and initializes the object (see NSManagedObject Class
Reference for a list of methods that do not cause faults to fire).
This process is commonly referred to as firing the fault.
Core Data automatically fires faults when necessary (when a persistent
property of a fault is accessed).
From what I can tell by reading the programming guide, seeing faults on relationships (links to other entities) is normal when looking at any particular entity. But seeing faults on the persistent property values is not mentioned. I believe that, in general, if the object is in memory, then its properties should not be faulted, but its relationships may be faulted.
The fact that the favoritesCollection entity was fully faulted (properties and relationships) and the fault did not get resolved revealed a problem. In this case it is consistent with the entity no longer existing in the database.