Tancrede Chazallet
Tancrede Chazallet

Reputation: 7245

Need to call removeObserver twice

I have a view that observe values of itself on init like this :

[self addObserver:self forKeyPath:@"focusPointOfInterestIndicator" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"exposurePointOfInterestIndicator" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"paused" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"previewLayerGravity" options:0 context:kSRCameraViewObserverContext];

And on dealloc, observers are removed as they should be like this :

[self removeObserver:self forKeyPath:@"focusPointOfInterestIndicator"];
[self removeObserver:self forKeyPath:@"exposurePointOfInterestIndicator"];
[self removeObserver:self forKeyPath:@"paused"];
[self removeObserver:self forKeyPath:@"previewLayerGravity"];

But unless calling it twice (with or without context, doesn't change anything), I have a crash when the view is deallocated cause the value are still observed. But I'm quite sure observers are added only once (since it's in init of object).

I just wonder if why it could be registered twice ? Or is it like by calling it twice, it let to the object to effectively remove observers ? If someone have any clue ?

Upvotes: 0

Views: 797

Answers (3)

RP Development
RP Development

Reputation: 120

init is the primary initializer of NSObjet that means init must be called in Apple's implementation of initWithCoder / initWithFrame with something like [super init];

so your sharedSetup is called twice

EDIT (thanks to And Ainu):

To be more specific, that's the init method of UIView which calls the initWithFrame method.

Upvotes: 2

Hussain Shabbir
Hussain Shabbir

Reputation: 15015

One more thing you can do is instead of observing in init method replace the same in loadView or awakeFromNib method. Then it will not called twice.

Upvotes: 0

Pratik Mistry
Pratik Mistry

Reputation: 2945

Its good practice if you use try catch every time you remove the observer.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    @try {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LocationSelected" object:nil];
    } @catch (id anException){
        //do nothing, obviously it wasn't attached because an exception was thrown
   }   
    [[NSNotificationCenter defaultCenter] addObserverForName:@"LocationSelected" object:nil queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *not) {
       //Someone posted the notification handle it here
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
     @try {
         [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LocationSelected" object:nil];
     } @catch (id anException){
         //do nothing, obviously it wasn't attached because an exception was thrown
     }
}

Upvotes: 1

Related Questions