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