Cocoa-Touch, NSManagedObject: Exception when setting a property - iphone

I have a NSManagedObject subclass, created by the XCode model interface.
This class has some NSString and NSNumber members, and a NSDate member.
When I try to set the NSDate member, I get the following exception:
2009-10-12 21:53:32.228 xxx[2435:20b] Failed to call designated initializer on NSManagedObject class 'Item'
2009-10-12 21:53:32.228 xxx[2435:20b] *** -[Item setDate:]: unrecognized selector sent to instance 0x3f7ed30
2009-10-12 21:53:32.229 xxx[2435:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Item setDate:]: unrecognized selector sent to instance 0x3f7ed30'
The date parameter is just like the others, except that instead of being a
#property (nonatomic, retain) NS{String,Number}* propname;
it's a
#property (nonatomic, retain) NSDate *date;
Btw, the Item instance I'm assigning on is just a regular [[Item alloc] init], no associated context or anything.
First I thought my NSDate* was faulty, then I tried assigning it [NSDate date], and even nil. It still crashes.
Any ideas?

You can't instantiate an NSManagedObject subclass without an associated NSManagedObjectContext (well you can as you've shown, but the results will almost certainly not be what you want).
The first line of the log hints at this:
2009-10-12 21:53:32.228 xxx[2435:20b] Failed to call designated initializer on NSManagedObject class 'Item'
All Objective-C classes have (by convention) a designated initializer, which is the initializer method that must be called, either explicitly or via an other convenience initializer. In the case of NSManagedObject this is -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:]. Failure to cause the designated initializer leads to undefined, and likely incorrect, behavior because the instance is not guaranteed to be properly initialized. I would guess that the NSManagedObject initializer sets up the machinery to support #synthesize'd property access for the Entity's attributes. Without this machinery, the instance may not think it can respond to the #synthesize'd calls and your call to setData: will cause a selector not found error.

Related

Objective-C property access: unrecognized selector sent to instance

I am new to objective-c, but coding for many years now. Somehow I don't get warm with Objective-C. I searched google and stackoverflow, but I think my problem is just to simple and stupid that no one has asked this yet.
My Code is based on DateSelectionTitles Example. http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html
I have an NSManagedObject
#interface Event : NSManagedObject
#property (nonatomic, retain) NSDate * date;
...
// Cache
#property (nonatomic, retain) NSString * primitiveSectionIdentifier;
All prperties are defined in my datamodel, except the primitiveSectionIdentifier (as in the apple example)
But when I call
NSString *tmp = [self primitiveSectionIdentifier];
I get the Exception
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Event primitiveSectionIdentifier]: unrecognized selector sent to instance 0x74850c0'
To put it simple:
Event *foo = [[Event alloc] init];
if (foo.primitiveSectionIdentifier) {
NSLog(#"YEAH");
}
throws the same exception. So I basically want to check if primitiveSectionIdentifier is nil. But when I access the property, it throws an exception? Do I need to alloc each property before I can check if it has a value?!
Which of the Objective-C basics am I not getting here?
Thanks a lot for responses!
There is only one way how this can happen without compiler warnings - you must have written #dynamic primitiveSectionIdentifier; in your implementation file. This means that you don't want to define the method because you believe it is already defined somewhere else.
You are using a NSManagedObject, do you know how it works? You declare methods without implementation (putting #dynamic in the implementation) and when the method is called, it is not found and a special handler [NSObject doesNotRecognizeSelector:] is called instead. This handler checks the Core Data model whether an attribute for the given selector exists and if it doesn't, it throws the exception you are seeing.
So, the problem might the caused by the fact that primitiveSectionIdentifier is not declared in your model.
You are using an older example program, which uses a different style of memory management; if you are compiling under the iOS 5 or 6, that may be causing the problem.
Try
NSLog(#"primitiveSectionIdentifier = %#", self.primitiveSectionIdentifier);
If it doesn't give you the string you are looking for then the problem is likely in that the string object was never initialized and is still set to nil. In that situation, the code would compile, but sending a selector to a nil pointer would throw up an exception.

Core Data: Setting Entity.Attribute, Type Issues

I'm currently trying to set up my entity by filling in the required attributes. I am doing this by parsing an XML response and assigning the attributes as they come up. The issue that I am running into is that I have what seems to be a type mismatch that results in my attribute set function throwing an "incorrect selector sent to function" error. I have gone into the debugger and noticed that always before assigning to my custEntity.name attribute, my type seems to be of NSCFString instead of NSString. I have done some searching as well as some tests and attempted fixes of my own but have been unable to get anywhere. Here is some relevant code and its effects.
Auto Generated and Combined into one file with my other entity definition, DataModelObject.h:
#interface Checkpoint : NSManagedObject {
#private
}
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * lat;
#property (nonatomic, retain) NSNumber * lon;
#property (nonatomic, retain) NSManagedObject * myRoute;
#end
DataModelObject.m
#implementation Checkpoint
#dynamic name;
#dynamic lat;
#dynamic lon;
#dynamic myRoute;
#end
What my current code looks like as a result of a suggestion to someone else with a somewhat similar problem elsewhere:
NSString *chkptName = [attributeDict objectForKey:#"name"];
checkpoint.name = [[NSString stringWithString:chkptName] stringValue];
This seems like some serious overkill to me, though I'm new to Objective-c and iPhone development so I dont know, it may be necessary, in any case this does not work. Before the execution of the second line the value of chkptName is the correct, human readable string that I would like to assign. In theory, if I understand the second line correctly, I simply re-declare an NSString with the value of ckptName, and the read out the actual value of it again with stringValue, which should be the same as getting the value of chkptName. However its in the second line that my app crashes with sigAbrt and when I attempt to check the values of my variable it shows that its of type NSCFString, with an invalid summary for the value. At this point I am at a loss on how to fix this. I have correctly modified entity attributes before and have not run into this problem before.
It is probably also worth noting that I started this out much simpler:
checkpoint.name = [attributeDict objectForKey:#"name"];
But this yielded the same sigAbrt and incorrect selector error.
Edit: Full Error as requested:
2011-08-02 07:25:00.544 MyApp[16011:207] -[NSCFString stringValue]: unrecognized selector sent to instance 0x5c174e0
2011-08-02 07:25:00.545 MyApp[16011:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString stringValue]: unrecognized selector sent to instance 0x5c174e0'
Edit2: Debugger Output:
(gdb) po checkpoint
<Checkpoint: 0x5a30730> (entity: (null); id: (null) ; data: {})
(gdb) po [checkpoint class]
Checkpoint
(gdb) po [checkpoint entity]
Can't print the description of a NIL object.
Any clarification that you can provide is much appreciated, if there is also some relevant code that I missed please ask and I will be happy to provide it if possible. Thanks!
-Karoly
I think you should take a careful look and verify that your checkpoint variable really is an instance of the Checkpoint class.
Verify that the class is properly setup in your Core Data model.
Set a breakpoint at run-time and print the object in the debugger: po checkpoint.
Verify the entity of the object at run-time with: po [checkpoint entity].
So it seems that the question has already been answered, but maybe for future reference:
If you get an error like this:
2011-08-02 07:25:00.544 MyApp[16011:207] -[NSCFString stringValue]: unrecognized selector sent to instance
It's pretty useful to really look at what it's saying:
unrecognized selector sent to instance means that an object has received a message that it cannot respond to or doesn't know how to.
-[NSCFString stringValue] shows you what message was sent (stringValue) and which object it was sent to (NSCFString).
From the message in the error we see that the error most probably happened when you called
checkpoint.name = [[NSString stringWithString:chkptName] stringValue];
Since that seems to be the only place where you call the message stringValue on an object (from what you've posted). And NSCFString is simply a subclass of NSString.
So you can't call stringValue on an NSString (which makes sense too). Just for clarification, but as I've read the issue has already been resolved. :)

EXC_BAD_ACCESS when setting synthesized (retained) property to nil

I get a bad access (objc_msgsend) when calling this line of code:
self.currentGameTeam = nil;
Where "currentGameTeam" is defined in the interface for a class called "MCState" as:
MNAvailableTeamContext *currentGameTeam;
And I synthesize a property for it:
#property (retain) MNAvailableTeamContext *currentGameTeam;
After setting NSZombieEnabled the console shows:
*** -[MNAvailableTeamContext release]: message sent to deallocated instance 0x5b3eba0
And the debugger trace shows that it comes from within the synthesized setter code:
#3 0x0001fa96 in -[MCState setCurrentGameTeam:] at MCState.m:44
I've looked at several other questions and threads and I can't find an answer that applies to my case. I don't understand why there would be a bad access if I've synthesized the property and I'm setting it to nil. What is especially odd is that there are at least 3 other properties in MCState which are defined and used in the exact same way as currentGameTeam, with the only difference being that they are different types:
MNUserContext *storedUser;
MNActiveGameContext *storedGame;
MNAvailableUserContext *storedGameUser;
MNAvailableTeamContext *storedGameTeam;
and
#property (retain) MNUserContext *currentUser;
#property (retain) MNActiveGameContext *currentGame;
#property (retain) MNAvailableUserContext *currentGameUser;
#property (retain) MNAvailableTeamContext *currentGameTeam;
and
#synthesize currentUser;
#synthesize currentGame;
#synthesize currentGameUser;
#synthesize currentGameTeam;
finally
self.currentUser = userContext;
self.currentGame = nil;
self.currentGameUser = nil;
self.currentGameTeam = nil; // Error occurs here
The rest of these all act normally - only currentGameTeam gives me trouble. Any ideas?
Somewhere, currentGameTeam is being released before you attempt to set it to nil. Setting a retained property to nil implies a release to be called. Calling release on an object that has already been released will result in a EXC_BAD_ACCESS. This is confirmed with your running with NSZombies enabled.
You can run with Instruments with the Zombies tool - it will give you more detail about all of the retains, releases and autoreleases leading up to the zombie call.
Do you have the ivar named currentGameTeam ?
I've had some bugs like this an usually tracked them down to a typo someplace where I meant to type currentGameUser but have typed currentGameTeam so I end up double-releasing one of the objects and not releasing another. I would try doing a Build and Analyze to and if that doesn't find anything try Run with Performance Tool > Leaks.
I say this since your code looks fine except you declare stored* and then declare and synthesize properties for current*, which looks like an inconsistency so there may be other places where this kinds of close-but-different typos may have occurred.
Last time set to nil should already set that to nil.
So the next time set to nil should not harmful. Not sure why crash.

Implementing Transient Properties

I am adding a transient property to my Core Data-based app, and I think I am missing something. In the Data Model Editor, I added a optional, transient, BOOL property called isUnderwater.
In my model's header file, I added: #property (nonatomic) BOOL isUnderwater;, then I implemented these methods in the implementation file:
- (BOOL)isUnderwater {
... implementation ...
return (ret);
}
- (void)setIsUnderwater:(BOOL)isUnderwater {}
But when I try to use isUnderwater as a condition in a NSPredicate, I get this error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath isUnderwater not found in entity <NSSQLEntity Wheel id=2>'.
Any ideas?
Thanks!
First, you can't use a transient property in a NSFetchRequest that is going against a SQLite store. When you are using SQLite the NSFetchRequest is translated into sql and run against the database, long before your transient is ever touched.
Also, you should not be implementing the accessors, you should be using #synthesize instead.
Next, if you are wanting to set the transient property then you should be setting it in the -awakeFromFetch and/or -awakeFromInsert instead of overriding the getter.
Next, your property should be called underwater and the #property definition should be:
#property (nonatomic, retain, getter=isUnderwater) NSNumber *underwater;
Note: even though you are declaring it a boolean in your model, it is still a NSNumber in code.
Lastly, setting the optional flag on a transient property has no value since it will be thrown away anyway.
Update
You can apply additional filters (even against transient properties) once the entities are in memory. The only limitation is that you can't use transient properties when you are going out to the SQLite file.
For example, you could perform a NSFetchRequest that loads in all of the entities. You could then immediately apply a second NSPredicate against the returned NSArray and further filter the objects down.

Coredata integration into existing application problem iphone

I'm integrating coredata into my existing application as given in http://wiresareobsolete.com/wordpress/2009/12/adding-core-data-existing-iphone-projects/.
I'm facing a problem in insertion of data. My data isn't getting inserted into the following entity.
I'm importing coredata framework into the class Editorial.
#interface Editorial : NSManagedObject {
NSInteger id;
NSString *type;
}
#property (nonatomic, assign) NSInteger id;
#property (nonatomic, retain) NSString *type;
And in Editorial.m I'm writing:
#implementation Editorial
#synthesize id, type;
In my .xcmodel also, Editorial is subclassing NSManagedObject and having the mentioned variables with corresponding types.
I think I'm missing something very obvious. But I'm not getting it. Generally while using coredata, if created at the beginning of the project, it automatically inserts attributes and they are not declared in interface and are synthesized with #dynamic. But while integrating coredata at later time, should the corresponding classes be created the way coredata creates them for us?
EDIT: This is how I'm inserting values for Editorial object.
self.managedObjectContext = appDelegate.managedObjectContext;
newEditorial = (Editorial *)[NSEntityDescription
insertNewObjectForEntityForName:#"Editorial"
inManagedObjectContext:self.managedObjectContext];
strTitle = [NSString stringWithFormat:#"%#",[object valueForKey:#"eletitle"]];
[newEditorial setEletitle:[NSString stringWithFormat:#"%#", strTitle]];
[newEditorial setElecompany:[NSString stringWithFormat:#"%#", strTitle]]; // CRASHING HERE
[self saveAction];
One more thing that it's crashing at the 2nd string insertion at shown line. I'm getting
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSManagedObject setElecompany:]: unrecognized selector sent to instance 0x4658800' at this line.
NSString *eleCompany exists in the specified coredata entity as well as the class. Also strTitle is containing string and not assigning it to eleTitle as well as eleCompany both of which are strings and exist in class as well as in coredata entity.
Can anybody please help?
This' really urgent.
Thanx in advance.
NSManagedObject instances probably do not contain NSInteger attributes — you probably meant to use NSNumber instead, which is a Core Foundation object type that can be serialized in Core Data.
id is a keyword and very likely reserved. Try naming your NSNumber attribute differently.
After updating your model with new attribute and relationship changes, you will always need to modify or recreate header and implementation files for your managed objects.