Reputation: 429
In Objective C how do I explicitly release an object owned by another object? Or perhaps equivalently inform the owning object that it does not own the child object anymore. Consider the following:
- (void) testWithNSString:(NSString *)val
{
NSData *data = [val dataUsingEncoding:NSASCIIStringEncoding];
// ...
// now I want to explicitly release data e.g. due to low memory
}
In [val dataUsingEncoding:NSASCIIStringEncoding]
an NSData
object is returned and I assume (due to general conventions of ownership) that it will be released, when val
is released. This seems acceptable from a non-leaking perspective. But this strategy raises two issues:
data
object immediately e.g. due to low memory?testWithNSString
to be left with an NSString val
object (after the testWithNSString
has returned), which suddently has ownership of new objects?Upvotes: 0
Views: 158
Reputation: 69027
In [val dataUsingEncoding:NSASCIIStringEncoding] an NSData object is returned and I assume (due to general conventions of ownership) that it will be released, when val is released
This is incorrect. dataUsingEncoding
will create a new NSData
object that has no relationship with val
(as to lifetime). It is an autoreleased
object and it will be released at the next cycle of the run loop (approx, we don't know exactly), unless you retain it somehow.
What if I want to explicitly release data object immediately e.g. due to low memory?
If you want the object to be released immediately, and you are using ARC, you can simply assign nil to its pointer:
data = nil;
If you are not using ARC, your best option is to wait for the run loop autorelease pool to do its job. Or you can create a local autorelease pool in your method, so that autoreleased objects are drained at the end of the method and not at the next run loop cycle. This will make a difference only in case of long-running methods (or chain of methods), so I don't know if it would make sense in your case.
What if I do not want the caller of testWithNSString to be left with an NSString val object (after the testWithNSString has returned), which suddently has ownership of new objects?
As I said, val
has no ownership of data
.
Summing this all up, your data
object is autoreleased and it will be pretty soon after your method ends (unless it is a long-running method); so data
memory will be recovered in an efficient way and I would not worry about it (unless it is a long-running method, as I said).
Upvotes: 1
Reputation: 40211
First of all, you should never ever release an object that you don't own. The returned NSData
object will not be released when val
is released. The two objects are completely independent (except that data
originated from val
).
dataUsingEncoding:
returns an autoreleased object. That means data
will be released at the end of the run loop.
If you are afraid that you will run low on memory and want it to release earlier you can use an NSAutoreleasePool
pool:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *data = [val dataUsingEncoding:NSASCIIStringEncoding];
// do something with data.
[pool release];
This will release data
when you release the pool.
Upvotes: 2
Reputation: 910
Assuming you're using ARC, setting val
to nil should release it.
Upvotes: -1