I am trying to implement a custom getter and setter for my custom HFObject , and my application crashed with a Message sent to deallocated instance error, despite using ARC.
I read every single entry, those that were written before ARC do not apply, and everything else did not help. I have the option to debug a zombie object enabled.
Custom HObject Setup
Inside HObject.h, I declared these four properties:
@property (retain) NSString *email; //Will use custom getter/setter @property (retain) NSString *firstName; //Will use custom getter/setter @property (retain) NSDate *date; //Will use custom getter/setter @property (nonatomic, retain) NSMutableDictionary *values;
In the HObject implementation, I removed the automatic receipt and configuration of email . firstName and date using @dynamic so
@dynamic email; @dynamic firstName; @dynamic date;
I also put the values dictionary in my init init
- (id)init { self = [super init]; if (self) { self.values = [NSMutableDictionary dictionary]; } return self; }
Custom getter and sender implementation
For my custom getter / setter. I redefined
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
and
- (void)forwardInvocation:(NSInvocation *)invocation
As below:
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSString *sel = NSStringFromSelector(selector); if ([sel rangeOfString:@"set"].location == 0) { return [NSMethodSignature signatureWithObjCTypes:" v@ :@"]; } else { return [NSMethodSignature signatureWithObjCTypes:"@@:"]; } } - (void)forwardInvocation:(NSInvocation *)invocation { NSString *key = NSStringFromSelector([invocation selector]); if ([key rangeOfString:@"set"].location == 0) { key = [key substringWithRange:NSMakeRange(3, [key length]-4)]; id obj; [invocation getArgument:&obj atIndex:2]; [self.values setObject:obj forKey:key]; } else { id obj = [self.values objectForKey:key]; [invocation setReturnValue:&obj]; } }
What I'm trying to do here is to save all property values in my values dictionary and get them from there.
Application crash
In the implementation of my view controller, I try to create a HObject and set the values for my properties, and then I write a dictionary of values to see all my values.
- (void)buttonPressed:(id)sender { HObject *obj = [[HObject alloc] init]; NSString *name = @"this is a string object"; obj.date = [NSDate date]; obj.email = @" email@website.com "; obj.firstName = [NSString stringWithFormat:@"%@", name]; NSLog(@"Values %@", [obj values]); }
At this point, the application crashes and this is my console log
2014-07-27 04:12:37.899 App[61501:60b] Values { Date = "2014-07-27 08:12:37 +0000"; Email = " email@website.com "; FirstName = "this is a string object"; } 2014-07-27 04:12:37.901 HeadsUp[61501:60b] *** -[CFString release]: message sent to deallocated instance 0x109473fe0
If you can help me, I would really appreciate it. I also include a debugging process in case this helps you
My debugging process (long, skip if you can already help me)
I initially created many of these objects and saved them in an array, and when I do this, as opposed to creating a single object. my application crashed a little differently.
My array:
@property (nonatomic, strong) NSArray *array;
Methods
- (void)createArray { int i = 1; //number of testobjs NSMutableArray *objects = [NSMutableArray arrayWithCapacity:i]; for (int j = 0; j<i; j++) { HFObject *obj = [[User alloc] init]; NSString *name = @"this is a string object"; [obj setObject:[NSDate date] forKey:@"Date"]; obj.email = @" email@website.com "; obj.firstName = [NSString stringWithFormat:@"%@", name]; [objects addObject:obj]; } self.array = [NSArray arrayWithArray:objects]; } - (void)buttonPressed:(id)sender { HObject *object = [self.array objectAtIndex:0]; NSLog(@"Values %@", [object values]); }
Failure Log:
2014-07-27 04:34:02.893 App[61623:60b] *** -[CFString isNSString__]: message sent to deallocated instance 0x1094988f0 (lldb)
Now this crash log is almost the same as the previous one, except that it did not record the values inside [object values]
Having studied the problem a bit, I looked in the left window (not sure what it really is called) of the debugger, and I saw this:

(Treat HFObject as HObject and dirtyValues as values , I renamed them for presentation purposes)
You can see that there is no value under the @"FirstName" key.
I did some similar tests where I changed the property values that I set and changed the data types. More often than not, the value of firstName did not matter, but not date . However, the value of email has always been present.
After examining the Types data, I realized that this was because email was a string literal that could not be freed. On the other hand, firstName and date were objects that could be freed.
The crash log refers to the CFString property, which I learned doesn't use ARC. I never created a Core Foundation object, so I decided to find out that it was created in setter by running [obj class] :
- (void)forwardInvocation:(NSInvocation *)invocation { NSString *key = NSStringFromSelector([invocation selector]); if ([key rangeOfString:@"set"].location == 0) { key = [key substringWithRange:NSMakeRange(3, [key length]-4)]; id obj; [invocation getArgument:&obj atIndex:2]; NSLog(@"%@", [obj class]);
After crashing again I got obj classes
2014-07-27 04:58:03.893 HeadsUp[61765:60b] __NSDate 2014-07-27 04:58:03.894 HeadsUp[61765:60b] __NSCFConstantString 2014-07-27 04:58:03.894 HeadsUp[61765:60b] __NSCFString 2014-07-27 04:58:03.904 HeadsUp[61765:60b] *** -[__NSDate release]: message sent to deallocated instance 0x109554370 (lldb)
Here you can see that date freed for some reason, and my line is now __NSCF lines.
I tried dropping strings to NSStrings using (__brigde NSString *)obj and any other possible way to associate the CF object with ARC, however that didn't work either.
That is all I have done. I appreciate any help.