have a problem with object setters in a class.
I have the class GEOImage, where things like description, title etc. will be saved according
to an image.
@interface GEOImage : UIImage
{
NSString *title;
NSString *imgDescription;
NSString *latitude;
NSString *longitude;
NSDictionary *editInfo;
}
@property (nonatomic, copy) NSString *title, *imgDescription, *latitude, *longitude;
@property (nonatomic, copy) NSDictionary *editInfo;
@end
Now i try to store a description out of another class:
self.chosenImage.imgDescription = @"description";
where chosenImage is of type GEOImage.
But i get the error:
-[UIImage setTitle:]: unrecognized selector sent to instance 0x939d220
2011-12-05 10:59:40.621 GeoPG[511:17c03] * Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[UIImage setTitle:]: unrecognized selector sent to instance 0x939d220’
If I’m looking in the debugger, the chosenImage is not NULL, and its been displayed correct in an image view.
Greets
s4lfish
We can safely infer that
chosenImageis notnil; if it werenil, sending it a message would simply do nothing, not crash.(Also, I’m assuming that you meant
titlerather thanimgDescriptionin your usage sample, or that you implementedsetImgDescription:to set thetitlein turn.)There are two possibilities:
Dead object
You created the image you stored to
chosenImageas a GEOImage, but then it died while you were holding on to it. Subsequently, a UIImage (as identified in the exception message) was created at the same address, so the pointer you still hold now points to a UIImage. You sent a message to it that only works on GEOImages, but it’s only a UIImage, so it doesn’t respond to the message, which is the exception.The cause of an object dying while you’re holding it is that either you didn’t retain it somewhere where you should have, or you released it somewhere where you shouldn’t have. Or possibly both.
Run your app under Instruments with the Zombies template. It will raise a flag when you hit this crash, and you can then investigate by clicking the button in that flag. Look at all of the Release and Autorelease events, starting from the end, to find the one that shouldn’t be there; then, if the release itself is unwarranted, take it out, or if it should be balanced by a previous retain, put one of those in.
One possible cause of the crash is that you declared the
chosenImageproperty asassign, but you should have declared it asretain/strong. If this is the problem, your Instruments findings will support it.Long-term, you should convert to ARC, which eliminates 90% of the cases where this problem could happen.
You never created a GEOImage in the first place
Just because you declared that
chosenImagewill hold a pointer to a GEOImage doesn’t mean it does. You can assign any object pointer there, and in many cases, the compiler doesn’t know if it isn’t actually a GEOImage.(They introduced a feature called “related result types” in a future version of Clang that should make this much less likely.)
At a guess, I’d say you’re doing something like this:
or this:
There is no reason to expect
takePictureto return a GEOImage (how should it know that’s what you want?), and it’s likely that+[UIImage imageNamed:](assuming you simply inherit it) won’t, either. Unless you create a GEOImage instance yourself, usingallocand an initializer, you cannot assume that any UIImage you get will be a GEOImage.The solution is to make it easy to create a GEOImage from a UIImage (which will involve wrapping this method), and then do that.
Once you have a live (not dead) GEOImage (not UIImage) in your
chosenImageproperty, it will work.