0

I have the following properties defined:

@property (nonatomic, retain) NSString *name_;
@property (nonatomic, retain) NSString *profilePicture_;
@property (nonatomic, retain) NSString *username_;
@property (nonatomic, retain) NSString *id_;

and I set them up in my init... like this:

-(id)initWithData:(NSDictionary *)data
{
    self = [super init];
    if (!self) {
        return nil;
    }

    name_ = [data valueForKey:@"full_name"];
    profilePicture_ = [data valueForKey:@"profile_picture"];
    username_ = [data valueForKey:@"username"];
    id_ = [data valueForKey:@"id"];


    return self;
}

with the following dealloc:

-(void)dealloc
{
    [name_ release];
    [username_ release];
    [profilePicture_ release];
    [id_ release];
    [super dealloc];
}

However the dealloc gives me an error:

pointer being freed was not allocated

Why is this? Do I have to do [[NSString alloc] init...] or [NSString stringWithString:]?

jscs
  • 62,161
  • 12
  • 145
  • 186
xonegirlz
  • 8,357
  • 18
  • 65
  • 122
  • What is your Xcode version? There is a problem with it in 3.x (don't remember whitch one)... – Jakub Apr 28 '12 at 16:15

3 Answers3

5

valueForKey: will return an autoreleased object, therefore you have no ownership. As they are all strings you can just call copy like this

name_           = [[data valueForKey:@"full_name"] copy];
profilePicture_ = [[data valueForKey:@"profile_picture"] copy];
username_       = [[data valueForKey:@"username"] copy];
id_             = [[data valueForKey:@"id"] copy];

you should also change your @property declarations to use copy as this is generally recommended for strings.

The other alternative is to go through the synthesised accessors but I generally avoid doing this in either init or dealloc

Paul.s
  • 37,649
  • 5
  • 66
  • 85
1

This is because you are assigning to backing variables in your initWithData. You should use rewrite your code as follows:

self.name_ = [data valueForKey:@"full_name"];
self.profilePicture_ = [data valueForKey:@"profile_picture"];
self.username_ = [data valueForKey:@"username"];
self.id_ = [data valueForKey:@"id"];

This would assign values through properties, which calls [retain] for you. The way your code is written now, the pointer is simply copied into ivars without calling [retain], which ultimately causes the issue that you describe.

Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • Or synthesize with variable: synthesize name_ = _name_; – Jakub Apr 28 '12 at 16:16
  • @SimpleMan Is this syntax available in Objectice C released with pre-4.x releases of Xcode? – Sergey Kalinichenko Apr 28 '12 at 16:18
  • 1
    @dasblinkenlight I think it was I've always synthesized ivars like that and I started on xcode 3.x – Paul.s Apr 28 '12 at 16:23
  • @Paul.s Thanks, it's nice to know. I'm very new to Objective C - I used 3.x for several months before 4.x came out, so I don't know how it was before 4.x. – Sergey Kalinichenko Apr 28 '12 at 16:27
  • I did this until someone else on SO pointed out how in Apple's Advanced Memory Management Programming Guide, the section titled [Practical Memory Management](http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html) includes a whole section titled 'Don’t Use Accessor Methods in Initializer Methods and dealloc'. – Dondragmer Apr 29 '12 at 22:43
  • @Dondragmer I took Rob Napier's advise on this (here is the [link](http://stackoverflow.com/a/1286227/335858)), he says it's good when you do it right, except when there is a possibility of subclasses overriding accessors. – Sergey Kalinichenko Apr 29 '12 at 22:55
  • @Dondragmer looking at that link I find it very disappointing advice, I'm not fond on the `you shouldn't do this, but I won't tell you why` aspect of it. If you understand the potential repercussions of using accessors then you will obviously know how to do it right without any issues. However for me I just avoid the use of accessors in these places as I know projects grow over time and assumptions I make now, may not be the same assumptions I make in the future, which could lead to nasty subtle bugs. – Paul.s Apr 30 '12 at 00:13
0

Since you are using data from dictionary, you should set values through properties using self keyword.

If it doesn't solve, then problem is probably not inside your class but perhaps where you create the instance of it. Try examining the Code where you allocate and release the instance of this Class.

You should also profile your app using Simulator & NSZombies n Determine where you over-release the object.

tGilani
  • 3,103
  • 3
  • 27
  • 50