Where to addObserver to NSNotificationcenter in a custom UITableViewCell?
Asked Answered
I

1

7

In my UITableViewCell I have a method initNotification which is called by the TableViewController in cellForRowAtIndexPath where the TableCells are created.

My Problem is that, every time this view is reloaded, the initNotification method is called again, so when the Notification appears, the NotificationHandle is called x-times!

I have tried to remove the Observer before adding it again with:

-(void) initNotification{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(handleNotificationOnOff:)
     name:[[NSString alloc] initWithFormat:@"%@",[self.light beckhoffOnOff]]
     object:nil];
}

but this do not work either. The Problem is, I cannot use a bool-flag or anything like that, because the Cells are always reinitialized by the ViewController.

Is there a proper way to remove the NotificationHandle form the NotificationCenter?

edit: This is how I create my custom TableViewCells

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    Light* l = [[staticModel.model getRoomAtIndex:[indexPath section]]getLightAtIndex:[indexPath item]];
    if([l typ]==ONOFF){
        TableCellLight *conof = [tableView dequeueReusableCellWithIdentifier:@"ReuseIDOnOff" forIndexPath:indexPath];
        LightOnOff *lonof = (LightOnOff*) l;
        [[conof label] setText: [lonof bezeichnung]];
        conof.light=lonof;

        [conof initNotification];
        cell = conof;
    }
   if([l typ]==DIMMER){
        TableCellLightDim *cdim = [tableView dequeueReusableCellWithIdentifier:@"ReuseIDDim" forIndexPath:indexPath];

        LightDim *ldim= (LightDim*) l;
        [[cdim label] setText: [ldim bezeichnung]];
        [[cdim slider]setValue:[ldim dimVal]];
        cdim.light=ldim;
        [cdim initNotification];
        cell = cdim;
    }
    if([l typ]==RGB){
        TableCellLightRGB *crgb = [tableView dequeueReusableCellWithIdentifier:@"ReuseIDRGB" forIndexPath:indexPath];
        LightRGB *lrgb= (LightRGB*) l;
        [[crgb label] setText: [lrgb bezeichnung]];
        crgb.light=lrgb;
        crgb.owner=self;
        [crgb initNotification];
        cell = crgb;
    }

    return cell;
}

Thanks

Imray answered 12/7, 2013 at 6:25 Comment(0)
B
13

Generally speaking the cell shouldn't be observing anything. The controller should be observing changes and pushing the updated information onto the cells.

Calling removeObserver: before adding the observer should work. If you were going to do anything in prepareForReuse or tableView:didEndDisplayingCell:forRowAtIndexPath: to reset the cell, that would be the code you use. You need to look at how you tested that it wasn't working and how you're reusing cells.

Balsa answered 12/7, 2013 at 6:39 Comment(11)
Thanks for the reply! I have figured out why removeObserver: doesn't work, because self is not the same anymore, every time the TableView is reloaded(and the cells as well) I get a new instance of every cell. Is there a way to force the cells to deallocate ?Imray
If you don't reuse the cells they should be released (as in, you don't have a reuse identifier). But that isn't ideal.Balsa
I have an reuse identifier but why ends that to so many instances of the same cell?Imray
You'd have to show the code. How are you counting the number of cell instances? The count should be just over the number of cells on screen if you're doing it correctly.Balsa
Every cell has it's own notification, in the notification handle I have a NSLog(self) so I could count how often the handle is called(should only called once!) - I have added the code where I create the cells to my question.Imray
Try using tableView:didEndDisplayingCell:forRowAtIndexPath: to tell each cell to remove itself as an observer when it is removed from the screen.Balsa
@Balsa would your recommend this for KVO as well?Niven
What if a cell contains a collection (or table) view, who is supposed to observe notifications? :-PBatch
@Batch consider using a child view controllerBalsa
@Balsa I'm using a VC with a table view, where some of the cells contain a collection view, those cells contain things that relate to models that need observing. Observing the model from the last point in the view class makes perfect sense to me, after all they know best what kind of data they care about. Nonetheless this time I actually went with observing only in the VC for now - the VCs refresh visible cells only. I believe iOS cells are pretty tricky after all.Batch
@Batch my cell is containing an Avplayer, for which i need to observe KVO to detect when the video has finished downloading.in that case what would you recommend?Delarosa

© 2022 - 2024 — McMap. All rights reserved.