osx - Removing reference to NSWindowController from AppDelegate on windowWillClose causes crash -
i have following method in gamewindowcontroller
(subclass of nswindowcontroller
):
- (void)windowwillclose:(nsnotification *)notification { appdelegate *delegate = [nsapp delegate]; [delegate removegamewindowcontroller:self]; }
the code removegamewindowcontroller in appdelegate is:
- (void)removegamewindowcontroller:(gamewindowcontroller*)controller { [self.controllers removeobject:controller]; }
self.controllers
nsmutablearray gamewindowcontrollers
.
the above code seems have race condition. randomly crash exc_bad_access
when close windows, every time if close windows @ once.
my guess arc deallocating window controller before or removegamewindowcontroller:
returns, leaving window dangling pointer controller. have tried adding controller.window.windowcontroller = nil;
no avail.
for reason, using (bool)windowshouldclose:(id)sender
delegate method instead suggested in https://stackoverflow.com/a/11782844/344544 works, not acceptable solution not called upon quit.
how can reliably remove window controllers array of controllers after each window has closed? there other delegate method gets called or nsnotification can subscribe fire after window has finished closing?
after lengthy investigation , step step running in debugger figured out source of problem , possible solution.
the window controller indeed being released @ point after end of removegamewindowcontroller:
along strong references include nswindow
. if window released before stack had unwound close
call on window itself, program crash while finishing function self
in particular case dangling pointer.
i unable find way notified after window had closed, such approach have had exact same problem.
in order ensure no reference window left anywhere on stack queued removal of window controller array happen subsequent event on runloop:
- (void)removegamewindowcontroller:(gamewindowcontroller*)controller { [self.controllers performselectoronmainthread:@selector(removeobject:) withobject:controller waituntildone:no]; }
Comments
Post a Comment