Question

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
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top