ios - Reloading row contains UITextField with a rightView causes infinite loop and memory overflow -
i'm facing strange bug reloading uitableviewcell contains uitextfield custom rightview.
i created simple example demonstrate bug:
my custom cell uitextfield:
@implementation tableviewcell - (instancetype)initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring *)reuseidentifier { if (self = [super initwithstyle:style reuseidentifier:reuseidentifier]) { _textfield = [[uitextfield alloc] initwithframe:cgrectmake(0, 0, 320, 44)]; _textfield.text = @"this text field"; [self.contentview addsubview:_textfield]; } return self; } @end my view controller uitableview:
@interface viewcontroller () <uitableviewdatasource> @property (weak, nonatomic) iboutlet uitableview *tableview; @property (nonatomic) uiview *rightview; @end @implementation viewcontroller - (void)viewdidload { [super viewdidload]; // additional setup after loading view, typically nib. // press reload row rightview self.navigationitem.rightbarbuttonitem = [[uibarbuttonitem alloc] initwithbarbuttonsystemitem:uibarbuttonsystemitemrefresh target:self action:@selector(reloadrow)]; // create rightview , store property _rightview = [[uiview alloc] initwithframe:cgrectmake(0, 0, 24, 24)]; _rightview.backgroundcolor = [uicolor greencolor]; [_tableview registerclass:[tableviewcell class] forcellreuseidentifier:@"cell"]; _tableview.datasource = self; } - (void)reloadrow { [_tableview reloadrowsatindexpaths:@[[nsindexpath indexpathforrow:0 insection:0]] withrowanimation:(uitableviewrowanimationautomatic)]; } - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { return 1; } - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { tableviewcell *cell = [tableview dequeuereusablecellwithidentifier:@"cell" forindexpath:indexpath]; cell.textfield.rightview = _rightview; cell.textfield.rightviewmode = uitextfieldviewmodealways; return cell; } @end that's it. press reload button. infinite loop starts, application hangs. after seconds, app crashes because uses memory:
terminated due memory error.
but, if don't store rightview in property, , create new view each time tableview dequeue cell, there no problem.
- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { tableviewcell *cell = [tableview dequeuereusablecellwithidentifier:@"cell" forindexpath:indexpath]; cell.textfield.rightview = [[uiview alloc] initwithframe:cgrectmake(0, 0, 24, 24)]; cell.textfield.rightview.backgroundcolor = [uicolor greencolor]; cell.textfield.rightviewmode = uitextfieldviewmodealways; return cell; } but rightview (in real app) not simple view don't want re-create everytime row shows up.
anyone knows why happened? why didn't happen if don't store rightview? reading.
you try add 1 view multiple superview. can't that. @property (nonatomic) uiview *rightview can have 1 superview. try delete subviews cell.textfield.subviews
- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { tableviewcell *cell = [tableview dequeuereusablecellwithidentifier:@"cell" forindexpath:indexpath]; (uiview *subview in cell.textfield.subviews) { if ([subview isequal:_rightview]) { [subview removefromsuperview]; } } cell.textfield.rightview = _rightview; cell.textfield.rightviewmode = uitextfieldviewmodealways; return cell; } or make fabric method return instance of rightview

Comments
Post a Comment