-1

The following class declaration seems to me alright. The 'name' property is deallocated in dealloc. self.name always release retain properly. But still Xcode analyzer gives warning about leaking. So is this style is not right?

Do I need to initialize any [[init] alloc] with autorelease as,

self.name = [[[NSString alloc] init] autorelease];

is it logical? If I use autorelease here, then why to release in dealloc. Even then I do not need to declare the property as (retain), isn't it?

-

@interface Student : NSObject
@property (nonatomic, retain) NSString *name, *address;
@end

-

@implementation Student
-(id)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        self.name = [[NSString alloc] init]; // warning here ... 
        // self.name = @"MyName"; 
    }
    return self;
}
- (void)dealloc{
    [_name release];
    [super dealloc];
}
@end

The what is the best way to it? This way?

NSString _n = [[NSString alloc] init]; 
self.name = _n;
[_n release];
karim
  • 15,408
  • 7
  • 58
  • 96

3 Answers3

1

See your [[NSString alloc] init] will create an object of retain count 1

Then you are assigning this object through property which is retained thus will retain it making its retain count to 2

Now In dealloc you are releasing it thus making its retain count to 1

So it's still in the memory unless you again release it.

The right way to use property is below

-(id)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        self.name = [[[NSString alloc] init] autorelease];
        self.name = @"MyName";
    }
    return self;
}

or

-(id)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        _name = [[NSString alloc] init];
        self.name = @"MyName";
    }
    return self;
}

or

-(id)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        String *str = [[NSString alloc] init];
        self.name = str;
        [str release];
        self.name = @"MyName";
    }
    return self;
}
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
  • 1
    Why alloc a new string, assign it to `self.name` and then replace it with a static string? The final `self.name = @"MyName"` makes anything before it redundant. – Jasarien Feb 13 '14 at 15:09
  • @Jasarien You are absolutely right but here he was talking about the leak and the below statement wasn't a major concern. – Inder Kumar Rathore Feb 13 '14 at 17:48
0

The rule states that any freestanding object should be [auto]released in the scope where it was created. Analyzer follows this rule and cannot bind any additional release in any scope except the one in init. Thus gives the warning.

You should autorelease allocated objects, or use ARC. It really simplifies everything.

user3125367
  • 2,920
  • 1
  • 17
  • 17
-2

The best way to assign value to property in init method is to use ivar. Using setters can be dangerous. Also assigning autorelease object to ivar is wrong because it will be deallocated when NSAutoreleasePool will drain. So the proper way will be:

-(id)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        _name = [@"MyName" copy];
    }
    return self;
}
igoris
  • 1,476
  • 10
  • 20
  • "Using setters can be dangerous"? Explain yourself, man! Also, why is this the "best" way? – Jasarien Feb 13 '14 at 15:07
  • It was explained thousand times: ftp://stackoverflow.com/questions/155964/what-are-best-practices-that-you-use-when-writing-objective-c-and-cocoa, http://stackoverflow.com/questions/192721/why-shouldnt-i-use-objective-c-2-0-accessors-in-init-dealloc, http://stackoverflow.com/questions/4264670/is-it-not-safe-to-call-accessor-methods-in-init-and-dealloc-methods-in-objective, https://mikeash.com/pyblog/friday-qa-2009-11-27-using-accessors-in-init-and-dealloc.html, etc. – igoris Feb 13 '14 at 15:14
  • About best way: you have two options to set value of property: use setter method or access ivar directly. Using setter can lead to side effects, while the only thing you need to worry with ivars - proper memory management. So, in my opinion, the way where you have less hidden pitfalls is much better. – igoris Feb 13 '14 at 15:17
  • I don't think those concerns are directly relevant in this particular case, and certainly not worthy of calling accessors outright dangerous. Mike states at the end of his post "In my opinion, it can go either way. The advantages aren't generally that great. The downsides are minor." - so it's definitely not a case of **you should never use accessors in init**. Definitely something to keep in mind, but probably overwhelming to a person new to Objective-C. – Jasarien Feb 13 '14 at 15:18
  • I never wrote "you should never use accessors in init". You just cannot be sure that you'll never overwrite setter or never make subclass that will lead to unwanted behaviour just because of using setter in init. – igoris Feb 13 '14 at 15:22