简体   繁体   中英

Remove an observer from an UITableViewCell when not used anymore

I am trying to tune my project after moving to ARC. My biggest problem is at the moment that objects are not released because of circular references. Eg on an UIView the dealloc is not called (which I previously used to release objects and put them on nil, because those objects are preventing the dealloc.

For UIViews I can do some logic on 'ViewDidDisappear' and decide f it is not needed anymore, but now I have a problem with UITableViewCells. In one I have an Notification observer, and the cell stays in memory if the observer is created.

What would be the best way to detect if an instance of (eg) the UITableViewCell is not needed anymore so I can remove the observer and the object can release itself from memory?

This is my header:

@interface DOArticleListCell : DOPrototypeCell {
    IBOutlet UILabel *_title;
    IBOutlet UILabel *_summary;
    IBOutlet UILabel *_site;
    IBOutlet UILabel *_update;
    IBOutlet UILabel *_unpublished;
    IBOutlet UIButton *_readButton;

    __weak DOArticle *_article;
    NSNumber* _isEditor;
}

@property (nonatomic, weak) DOArticle *article;

- (void)updateReadButton;
- (IBAction)toggleReadButton:(id)sender;

@end

(The prototype cell just has one function called 'populateCell'.)

Ps. I need the observer to update the 'read' label when the detailViewController being called when the cell is selected is opened.

You most likely do not want to use an observer on your cell. Why not? Your cells are being reused. Let's say you have 400 items in your table view. Only about 8 will be displayed on screen at any given time. That means that only 8 or 9 instances of your cell will be kept in memory and re-used when the user scrolls. That means that you would have to remove the observer every time a cell gets scrolled out of view and you'd need to add a new observer for the re-used cell. You would do that by overwriting the cell's prepareForReuse method. However, saving any kind of state (like marking a cell as being 'read') should not be done in the cell, but in your model.

Since in your case a user action triggers the updating of the read state, you can simply set your data model item to read in tableView:didSelectRowAtIndexPath: and then explicitly update that one cell by either calling a custom method on your custom cell or by calling [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

Hope it helps.

尽管有ARC,您仍然可以在类中实现-(void)dealloc并调用

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"yourNotName" object:nil]

Your design with observers can maybe be improved. It seems much more expedient to make the controller containing the view the observer of whatever you want to react to. Then remove yourself as observer when in the view controller's viewWillDisappear .

When receiving the notification, you should just change your table view's datasource . Then you can check if the cell that should get it is visible or not. If yes, update it, otherwise it should display automatically with the new information once it scrolls into view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM