0

In a project I have a class say "A", there are many other class that are observing class "A"'s property values.

Sometimes the class "A" instance gets deallocated and observees fails resulting in crash!

Is there any way to remove all the observers from class "A"? Something like this:

-(void) dealloc{
    [remove allObservers forKey:@"theKey"];
}
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140

2 Answers2

2

In short, sadly no. KVO is made so that it gets you in the end, unfortunately.

I've struggled with this thing before, and I found the following two solutions:

  1. Use a proxy method to register for observation in your observee, which will maintain a list of weak references to observers.
    Ideally, you'd want a proxy method for removing observers as well, so that your list is updated accordingly (although, since they are weak references in your list, it wouldn't hurt if some observer removed itself using standard KVO instead of your proxy method, and then deallocd itself).
    In case your observee gets deallocated, it should inform all observers (using a protocol), or just remove them outright itself. For the last one, using exceptions might come in handy as well (I am aware that exceptions are evil in Obj-C, but what to do):

    @try 
    {
        [self removeObserver:observee forKeyPath:@"path"];
    }
    @catch (NSException * __unused exception) {}
    
  2. Use some abstraction from KVO. There are a couple of projects that come to mind such as RZDataBinding and MAKVONotificationCenter (despite it's name, it actually pertains to KVO)

insys
  • 1,288
  • 13
  • 26
0

You should keep "A" class alive until there are other objects observing its property values. Maybe it gets deallocated because you're not correctly handling its reference.

You should check if "A" needs a 'strong' reference. When you don't need "A" anymore (i.e.: you're popping a view controller, you are refreshing a table, you're clearing a scrollview), you should also remove any observer attached to it (and be able to do it).

Luke47
  • 1,583
  • 3
  • 11
  • 14