Objective C, A Question about releasing an object - objective-c

If I do something like
address = [[NSString alloc] initWithData:addressData encoding:NSASCIIStringEncoding];
Then I know that I need to do like [address release] after I am done with using it.
Because "alloc" increases the reference count of "address" variable so that I need to do
[address release]
But I am not sure that I need to release if I do something like
NSData *addressData = [NSData dataWithBytes:buf length:address_len];
I don't see any "alloc" in this statement..So do I still need to do [addressData release] after I am done with this?
Thanks in advance...

No, you don't. You only need to release (or autorelease) an object if the method you got the object from is alloc, contains the word copy, or if you've retained the object.

Nope. In this case you can safely assume that the memory is autoreleased.
All explained in the Memory Management Ownership Policy

You do not need to do the release in your second example. The general rule is that you are responsible for a release if you call alloc, retain, or copy.

No, there is no need to release in your second statement. If you alloc, copy, new, then you should release the objects.
Objective C Memory Management for Lazy People has very useful info as to when to release objects.

Related

How memory is managed for an object that is created but not assigned to any pointer?

This might be a stupid question, but it keeps bothering me.
Say if we have a method that takes an NSString object as its parameter and does something with the NSString object,
- (void)someMethod:(NSString *)str
{
//do something with str
}
Consider this code
[someObject someMethod:[[NSString alloc] initWithFormat:#"Hello World!"]];
Since alloc has been used in creating the string as parameter of someMethod, it has to be balanced by release no matter explicitly in pre-ARC environment or implicitly under ARC. But it seems there is no way we can get a pointer to the string as we have never assigned it to any pointer.
So my question is, first, is this way of passing parameter prohibited in writing objective c code? If no, then how objects created this way get released? And finally, does this code lead to memory leak?
Just for the record, I understand the above code is written
NSString *string = [[NSString alloc] initWithFormat:#"Hello World!"];
[someObject someMethod:string];
// [string release]; depending on ARC or non-ARC
Well, in fact, that object is assigned to the variable named str, which is a parameter of your method. You can manage the memory inside your method via that pointer, although methods aren't supposed to take ownership of their arguments (except see below).
ARC knows what to do in this situation -- it will either autorelease the object or add a release once the method is finished.
Under MRR, your snippet would be a leak; the correct way to avoid that is also to send autorelease:
[someObject someMethod:[[[NSString alloc] initWithFormat:#"Hello World!"] autorelease]];
or to use your last snippet (putting the string into a temporary variable and releasing later).
As a slightly esoteric option, it is possible for your method to declare that it owns the argument, by using the ns_consumed attribute:
- (void)someMethod:(NSString *) __attribute__((ns_consumed)) str;
This indicates that your method should send release to the object before it returns -- ARC will also take care of that.
So my question is, first, is this way of passing parameter prohibited in writing objective c code?
No. It's perfectly legal.
If no, then how objects created this way get released?
ARC will take care of it for you. If you do your own reference counting, then you can add it to the autorelease pool before it goes out of scope:
[someObject someMethod:
[[[NSString alloc] initWithFormat:#"Hello World!"] autorelease]];
^^^^^^^^^^^
And finally, does this code lead to memory leak?
Not in ARC. In MRC, you would need to add the -autorelease.
The static analyzer would also point out that leak.
There's no reason to not write code as you ask for consideration on… nothing prohibited in the slightest. These objects get released in the same manner that any other object gets released. Your lack of a variable to store the pointer in at the top level isn't important because the Objective C runtime knows about the object.

Does the NSString returned from NSArray objectAtIndex as autorelease or retain

I have a string returned back from an array, just wonder if I need to release it after using it.
Have a look at this blog post, which does a great job summarizing the rules for Objective C memory management: http://interfacelab.com/objective-c-memory-management-for-lazy-people/.
In particular, rule #1 applies here - you only need to release an object if you own it and you own it if you alloc, copy or new it (or if you explicitly retained it). You didn't do any of those things, so you don't need to release it.
Whether it's autoreleased or not depends on how the string was originally created but you don't need to worry about that since you are not responsible for releasing it.
The objects returned from -objectAtIndex: are technically both.
The code looks something like this:
-(id) objectAtIndex:(NSUInteger) index
{
return [[objects_[index] retain] autorelease];
}
So they don't belong to you, but if you remove it from the array, it won't be immediately deallocated.
autoreleased.
That is with (almost?) any object returned by a method, it would make memory management overly complicated if it wasn't. It is why we all love autorelease.

Memory management, objective c

Suppose there is a string of type NSSTring
NSString *string;
There is array called testArray, which is array of string objects
string=[testArray objectAtIndex:1];
Do we need to give
[string release]
or not?
No, You needn't do
[string release]
You must release object only if you allocate memory for it. Check this Memory Management Policy for more detail information about alloc and release.
no .. in this case not.
if you get a string from a function, it has usually the autorelease flag and will get released later.
You need to release it if you retain it, if you alloc it or copy it.
You should read: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH
In this case you do not have to release the string. You only release the Objects which you own (created through alloc/init, copy or retain). Go through the memory management doc by Apple. In this case, testArray owns the string. Hence it takes care of releasing it when no longer required
No need to release. You have to release only the objects that you have allocated.
Only if you also called [string retain]. Otherwise the memory is managed by NSArray. you might call [string retain] if you need to remove it from the array, but still keep a reference to it.

Releasing objects created by functions

I'm learning obj-c and I have a question about memory management:
Say I have a function that returns an NSDictionary, "fDictionary",
NSDictionary *fDictionary {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], #"blah",nil];
return dict
}
that is called by a particular method:
-(int)fNumber {
NSDictionary *f = fDictionary();
return [[f objectForKey:#"blah"] intValue];
}
What I'm unclear about is how/where I should be releasing the NSDictionary object.
Should I release it in the method, or autorelease it in the function?
If the function was written properly, the dictionary is autoreleased, so you don't have to release it at all. It will be released soon, by the autorelease pool.
You only release what you yourself retain or copy. These are the things you "own". Be sure not to release them too early. The usual point is before the end of the function they are allocated or retained in, if they are local. If they are ivars, the best point is, usually, the dealloc of the class to which the ivar belongs.
Without knowing anything about fDictionary it's difficult to be sure, but the convention followed in most Object C code is as follows:
You own it if the instance was created with an alloc or copy
You own it if you retain it
Otherwise you don't own it
If you don't own it you should not release it.
So by convention, the function would return an autoreleased object and you wouldn't need any extra management in your method.
The general rule is if your code alloc's something, you need to release or auto-release it.
If this was someone else's function, you would expect that the returned dictionary was autoreleased - which is the convention here. I would ensure that fDictionary returns an autoreleased NSDictionary.
If you have received an object from a method which name begins with “alloc”, “new”, “copy”, or “mutableCopy”, you have to release or auto-release it. Otherwise it is already autoreleased.
If you have retained something, you have to release it, nothing else will do that for you.
Every Obj-C programmer must read Memory Management Guide.
No.
NSDictionary dictionaryWithObjectsAndKeys: (which is really just [[[NSDictonary alloc]initWithObjectsAndKeys:, nil]autorelease]) returns an autoreleased NSDictionary. This means the dictionary will automatically be released when the computer decides it is no longer needed.
If in fDictionary() the dictionary was alloced, you would need to release it manually. It is a rule of thumb to always return autoreleased objects from functions/methods, so the user of the functions/methods does not have to worry about memory management.

Reference on when to release in Objective-C

I'm having a recurring problem in Objective-C. I'm either releasing things too many time, or not enough. or perhaps I'm not retaining them enough...
Can someone point me at a good reference that will give me a rule of thumb on when I need to retain and release?
For example:
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
if I alloc an object and only need it in that method, do I need to release it? retain it?
Obviously, if I retained something, I needtorelease it, but beyond that, I get a bit lost.
The rules are generally pretty simple. If you get an object in one of the following ways:
id obj = [[MyObject alloc] init];
id obj = [myObject retain];
id obj = [myObject copy];
id obj = [myObject mutableCopy];
then you need to release it at some point -- in the same method, or your dealloc method, generally. In other words, balance your calls to alloc, retain, copy, and mutableCopy with a matching release call.
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
This happens rarely. The documentation for the called method should specify that you are responsible for releasing the returned object; otherwise, you should assume you're receiving an autoreleased object.
if I alloc an object and only need it in that method, do I need to release it? retain it?
Yes, you need to release it (but you don't need to retain it). (You can also use one of the convenience methods that return an autoreleased object if you're only going to use it in that method.)
There is one and only one canonical reference: Apple's Memory Management Guide for Cocoa or iPhone.