ios - Random EXC_BAD_ACCESS when adding subview with ARC -
my app working on simulator when test app on device random exc_bad_access , app crashes.
after few days of testing think have found code causing error. @ point need add subviews controller's main view, user interacts app , subviews removed superview , new subviews added. if don't ever remove subviews app not crash if remove them, app gets exc_bad_access , crashes.
it seems subviews removed release msg when released or that... first app i'm using arc i'm missing something...
here's code involved:
#define kwordxxx 101 #define kwordyyy 102 ... // called after user interaction, removes // old subviews (if exist) , add new ones - (void)updatewords { [self removewords]; if (self.game.move.wordxxx) { wordview *wordxxx = [self wordviewfortypexxx]; wordxxx.tag = kwordxxx; // self.wordsview view subviews added [self.wordsview addsubview:wordxxx]; } if (self.game.move.wordyyy) { wordview *wordyyy = [self wordviewfortypeyyy]; wordyyy.tag = kwordyyy; [self.wordsview addsubview:wordyyy]; } } // remove old words if exist - (void)removewords { wordview *wordxxx = (wordview *)[self.wordsview viewwithtag:kwordxxx]; wordview *wordyyy = (wordview *)[self.wordsview viewwithtag:kwordyyy]; if (wordxxx) { [wordxxx removefromsuperview]; } if (wordyyy) { [wordyyy removefromsuperview]; } }
here how subviews created. i'm not particularly proud of code , needs refactoring need understand why not working before:
- (wordview *)wordviewwithframe:(cgrect)frame andtype:(wordtype)type { wordview *wordview = nil; if (type == systemword) { frame.origin.y += 15; wordview = [[systemwordview alloc] initwithframe:frame]; } else if (type == startword) { wordview = [[startwordview alloc] initwithframe:frame]; } else if (type == userword) { wordview = [[userwordview alloc] initwithframe:frame]; } else { wordview = [[rivalwordview alloc] initwithframe:frame]; } return wordview; } - (wordview *)wordviewfortypexxx { wordtype type = self.game.move.wordtype; wordview *wordview = nil; cgrect wordviewframe = cgrectmake(0, 0, self.scoreview.frame.size.width, 35); wordview = [self wordviewwithframe:wordviewframe andtype:type]; wordview.word = self.game.move.word; return wordview; } - (wordview *)wordviewfortypeyyy { wordtype type = self.game.move.wordtype; cgfloat y = self.game.move.word ? 35 : 0; wordview *wordview = nil; cgrect wordviewframe = cgrectmake(0, y, self.scoreview.frame.size.width, 35); wordview = [self wordviewwithframe:wordviewframe andtype:type]; wordview.word = self.game.move.word; if (self.game.move.word && [wordview iskindofclass:[playerwordview class]]) { ((playerwordview *)wordview).points = [nsnumber numberwithinteger:self.game.move.points]; } return wordview; }
this working while , crashes. mean, views removed , added few times , seems ok after while app gets exc_bad_access.
any eternally appreciated!
ps: sorry english
edit: can't use zombies on device , can't see stacktrace.
this if type "bt" on lldb after exc_bad_access:
* thread #1: tid = 0x2503, 0x3bb735b0 libobjc.a.dylib`objc_msgsend + 16, stop reason = exc_bad_access (code=1, address=0x11d52465) frame #0: 0x3bb735b0 libobjc.a.dylib`objc_msgsend + 16 frame #1: 0x3473f6fe foundation`probegc + 62 frame #2: 0x34745706 foundation`-[nsconcretemaptable removeobjectforkey:] + 34 frame #3: 0x360b3d5c uikit`-[_uiimageviewpretiledimagewrapper dealloc] + 80 frame #4: 0x3bb75488 libobjc.a.dylib`(anonymous namespace)::autoreleasepoolpage::pop(void*) + 168 frame #5: 0x33e16440 corefoundation`_cfautoreleasepoolpop + 16 frame #6: 0x347ea184 foundation`__nsthreadperformperform + 604 frame #7: 0x33ea8682 corefoundation`__cfrunloop_is_calling_out_to_a_source0_perform_function__ + 14 frame #8: 0x33ea7ee8 corefoundation`__cfrunloopdosources0 + 212 frame #9: 0x33ea6cb6 corefoundation`__cfrunlooprun + 646 frame #10: 0x33e19ebc corefoundation`cfrunlooprunspecific + 356 frame #11: 0x33e19d48 corefoundation`cfrunloopruninmode + 104 frame #12: 0x379dd2ea graphicsservices`gseventrunmodal + 74 frame #13: 0x35d2f300 uikit`uiapplicationmain + 1120 frame #14: 0x0005bd40 dr. cuaicap`main(argc=1, argv=0x2fda8d10) + 116 @ main.m:16 frame #15: 0x3bfafb20 libdyld.dylib`start + 4
discussion comments -
you're right, zombies work in simulator - though suspect crash reproduce in simulator well. few cases app crash on device, not on simulator. maybe give try ensuring use simulator of same ios version. couldn't find info on _uiimageviewpretiledimagewrapper, key solving this.
this answer suggests _uiimageviewpretiledimagewrapper
related -[uiimage resizableimagewithcapinsets:]
.
comments op:
at point creating uiimageview based on resizable uiimage setting image before setting final size of uiimageview. seems somehow end corrupting memory due resizing of uiimage
Comments
Post a Comment