2

I am doing some allocation as

self.xyz = [[NSDictionary alloc] init];

Is it a good idea of retaining a property such like that? Or

will it be better to do such as:

NSDictionary *zzz = [[NSDictionary alloc] init];
self.xyz = zzz;
[zzz release];

My concern here is, I have seen some places people retaining such as:

self.xyz = [[NSDictionary alloc] init];

which means the retain count is 2. So what's the best way to reduce a count here to one.

Thanks. Just trying to clear some memory management concept clear a little more.

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
topgun
  • 2,463
  • 8
  • 31
  • 46
  • possible duplicate of [Autorelease vs. Release](http://stackoverflow.com/questions/2776494/autorelease-vs-release) – jscs Jan 10 '12 at 19:04
  • Just want to add some spice to it, so lets say at some method if I clear the retain count as self.xyz = nil; at dealloc i just specify it as [xyz release]; Making sure that the method is always called. – topgun Jan 10 '12 at 19:08
  • possible duplicate of [Local variable assign versus direct assign; properties and memory](http://stackoverflow.com/questions/3066848/local-variable-assign-versus-direct-assign-properties-and-memory) – Caleb Jan 10 '12 at 19:14
  • Also duplicates: http://stackoverflow.com/q/7395253/ http://stackoverflow.com/q/8605078/ http://stackoverflow.com/q/5447063/ http://stackoverflow.com/q/7017046/ and there are plenty more. – jscs Jan 10 '12 at 19:20
  • Here's another: http://stackoverflow.com/q/3549649/ – jscs Jan 11 '12 at 03:06

7 Answers7

3

This depends on how you've handled the property xyz. If you did

@property (nonatomic, retain) NSObject *xyz;

then xyz has a retain on the NSDictionary, so the second (3 line) version is best.

PengOne
  • 48,188
  • 17
  • 130
  • 149
2

I usually would do this:

self.xyz = [[[NSDictionary alloc] init] autorelease];

Or if the class has a convenience method then use it like so:

self.xyz = [NSDictionary dictionary];

Or, just use ARC and let it do the work for you in this instance.

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
2

I'm assuming we're talking about best practices when NOT using ARC.

In a manual memory management environment, the first approach is flat out wrong because as you pointed out, the retain count is at 2. The proper way to do a one liner is like so:

self.xyz = [[[NSDictionary alloc] init] autorelease];

Going through the synthesized setter (assuming xyz is declared with the retain directive), adds 1 to the retain count in addition to the 1 being added by alloc/init. The autorelease is there to balance this out.

The second approach that you detailed is functionally equivalent, but considered a better practice on embedded devices because of the relatively small amounts of memory available. You create an object, assign it to the property and release the original temporary object immediately. In the former approach, the object is placed into an autorelease pool and released at a later point in time.

Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • It's not equivalent. The autorelease has more overhead (putting it on the autorelease pool when you autorelease it; and an extra operation it has to do when you drain the autorelease pool) – newacct Jul 09 '12 at 19:44
  • I said functionally equivalent, meaning the outcome is the same. You'll notice in the next sentence I explain that it's better to tightly control memory on embedded devices. This is all negated by ARC anyway. – Mark Adams Jul 09 '12 at 21:12
1

I think you should use autorelease as a best practices for your code.

AAV
  • 3,785
  • 8
  • 32
  • 59
0

The second approach is the best to maintain retain count as 1.

Bharathi
  • 485
  • 6
  • 16
0

You have always to balance memory-management equation, if not, you could have memory leaks.

In your example it depends on xyz memory management policy.

If xyz has a retain policy, you have a retain count of two. It's a common mistake and you have a memory leak.

@property (retain, nonatomic) SomeClass* xyz;

If xyz has an assign policy, you don't increment the retain count

@property (assign, nonatomic) SomeClass* xyz;

In conclusion, if you use a retain policy, the second snippet you provided is the right way. Obviously you have to remember to release that property in dealloc method.

- (void)dealloc
{
   [xyz release];     
   [super dealloc];
}

Hope it helps.

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • however, it would also be a mistake to have a retain count of 1 when you have an assign policy – newacct Jul 09 '12 at 19:45
  • @newacct ah ok I see. I mean that the retain count is 1 since it has allocated the object with alloc-init. Assign the object to a property with an assign property has no effect. Is this not clear from my answer? – Lorenzo B Jul 09 '12 at 20:22
  • @newacct I modified my answer. Do you think it's more clear? Thanks. – Lorenzo B Jul 09 '12 at 20:24
  • nevermind, what you said before was more correct than now (it does have retain count 1). it is just that it is not compatible with the point of using an assign property – newacct Jul 09 '12 at 21:37
-7

In my humble opinion,

self.xyz = [NSDictionary alloc]

will cause memory leak. You need to release manually.

You can do this

xyz = [NSDictionary alloc]

After that even I have the same question. Which approach is better? and why?

mbh
  • 3,302
  • 2
  • 22
  • 24
  • 3
    That code only allocates memory and does not release either it but does not initialize the object so is even worse. – mmmmmm Jan 10 '12 at 18:57
  • thats exactly my point. Hence i said it will cause memory leak. Did you even read it? I was not tackling initialization. Whats wrong in initializing later? – mbh Jan 10 '12 at 19:00
  • The second approach is the best to maintain retain count as 1. – Bharathi Jul 09 '12 at 08:43