iossingletonuiaccelerometer

Retain an ivar that holds a pointer to [UIAccelerometer sharedAccelerometer]?


I'm using manual reference counting and Xcode 4.5.

I declared an ivar:

UIAccelerometer *accelerometer;

accelerometer was NOT a property. And I had this code in one method:

accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.delegate = self;

In a second method I had:

accelerometer.delegate = nil;

and in a another method that runs later I had:

accelerometer.delegate = self;

With this setup I occasionally (rarely and seemingly randomly) got the following abort:

'NSInvalidArgumentException', reason: '-[NSPathStore2 setDelegate:]: unrecognized selector sent to instance xxx

After lots of frustration looking for the reason for this abort I tried putting a retain on accelerometer when it was first used and after that there have been no aborts. But I'm worried that the retain didn't fix the real problem. The reason for thinking of this "solution" is that the abort message was complaining about a call to setDelegate and in the section of code that seemed to be relevant the only delegate I was setting was on accelerometer. But I don't understand why this should fix it and I'm worried that the retain is just shifting code around in a way that happens to hide the problem.

The way I understand it is that

accelerometer = [UIAccelerometer sharedAccelerometer];

creates a singleton instance that will have the same address for the duration of the instance it is in, and that address is being assigned to accelerometer, which also exists for the duration of the instance. If that is the case why does retain change anything?

Can the sharedAccelerometer singleton get deallocated before the instance it is in gets deallocated?


Solution

  • If accelerometer is an ivar, it is correct to retain whatever object you put there... So this code

    accelerometer = [UIAccelerometer sharedAccelerometer];
    accelerometer.delegate = self;
    

    Should be

    accelerometer = [ [ UIAccelerometer sharedAccelerometer ] retain ] ;
    accelerometer.delegate = self;
    

    And in -dealloc, add

    [ accelerometer release ] ;
    accelerometer = nil ;