Idiomatic short lifespan local objects akin to RAI

2019-07-20 08:58发布

问题:

I came across this fragment of Objective-C:

NSNumber *theBalance = 
    [[[NSNumberFormatter alloc] init]
     numberFromString: [textField text]];

This seems to leak the NSNumberFormatter. In C++ I would do one of two things:

  1. use auto (i.e. stack) storage for the NSNumberFormatter
  2. use RAII (e.g. shared_ptr) to manage the life of the NSNumberFormatter

In Objective-C neither of these options seem to be possible. I tried on the stack:

NSNumberFormatter fmt;

But this doesn't compile. As far as I can find there's no direct equivalent of RAII in Objective-C. I'm probably looking at the problem from the wrong angle as a mainly C++ programmer, so:

  1. In the general case what's the correct, idiomatic (modern) Objective-C way of handling the life of objects like the NSNumberFormatter here? Do I really have to do it explicitly myself?
  2. In the specific case is there a better way of solving the actual problem?

回答1:

Most of the classes like NSString, NSArray, and so on, have the convenience constructors like, [NSString string] and [NSArray array] which return the autoreleased objects. NSNumberFormatter doesn't have any convenience constructors. So, you can send a autorelease message to let it autoreleased when the autorelease pool drains.

NSNumber *theBalance = [[[[NSNumberFormatter alloc] init] autorelease]
                       numberFromString: [textField text]];

If you want to retain(own) the reference of the object, you can omit the autorelease and release it later when you are done with it. You do it like this,

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSNumber *theBalance = [numberFormatter numberFromString: [textField text]];

// Later... somewhere in your code...
[numberFormatter release];

I know the above is not a detailed explanation. I'd suggest you to read this post by which, I hope, you would get some clear idea about memory management!