EXC_BAD_ACCESS с IBACTION - PullRequest
       21

EXC_BAD_ACCESS с IBACTION

24 голосов
/ 15 января 2010

Я много читал об этой проблеме, но моя, похоже, все же как-то отличается. Итак, насколько я понял, EXC_BAD_ACCESS возникает с проблемами управления памятью.

Дело в том, что мой, кажется, (! :)) не там. Дело в том, что я просто добавил кнопку в IB, закругленный прямоугольник, без изображения. Я подключил его к IBACTION, который я определил в своем классе. Кстати, этот метод ничего не делает (!).

В любом случае, как только я нажимаю кнопку, приложение вылетает с сообщением «EXC_BAD_ACCESS».

Я, конечно, не переусердствую, насколько я понимаю, то есть. Что там не так?

Есть какие-нибудь подсказки?

Это мой консольный журнал:

Loading program into debugger…
sharedlibrary apply-load-rules all
Program loaded.
target remote-mobile /tmp/.XcodeGDBRemote-148-79
Switching to remote-macosx protocol
mem 0x1000 0x3fffffff cache
mem 0x40000000 0xffffffff none
mem 0x00000000 0x0fff none
run
Running…
[Switching to thread 11779]
[Switching to thread 11779]
(gdb) continue
2010-01-15 09:16:34.800 FlightControl1[1899:207] Table loaded
2010-01-15 09:16:35.200 FlightControl1[1899:207] 23
2010-01-15 09:16:35.350 FlightControl1[1899:207] debug
Program received signal:  “EXC_BAD_ACCESS”.
(gdb) 

Вот что я получаю после того, как поднялся в стек:

#0  0x31ec3ebc in objc_msgSend ()
#1  0x33605784 in -[UIApplication sendAction:to:from:forEvent:] ()
#2  0x336056ec in -[UIApplication sendAction:toTarget:fromSender:forEvent:] ()
#3  0x336056b4 in -[UIControl sendAction:to:forEvent:] ()
#4  0x3360530c in -[UIControl(Internal) _sendActionsForEvents:withEvent:] ()
#5  0x33605f8c in -[UIControl touchesEnded:withEvent:] ()
#6  0x335fd9ac in _UIGestureRecognizerUpdateObserver ()
#7  0x30da1830 in __CFRunLoopDoObservers ()
#8  0x30de9346 in CFRunLoopRunSpecific ()
#9  0x30de8c1e in CFRunLoopRunInMode ()
#10 0x332e7374 in GSEventRunModal ()
#11 0x335adc30 in -[UIApplication _run] ()
#12 0x335ac230 in UIApplicationMain ()
#13 0x000027a8 in main (argc=1, argv=0x2ffff4d8) at /Users/SomePath/main.m:14

Ответы [ 3 ]

53 голосов
/ 24 февраля 2010

Меня тоже пытали несколько часов. Как оказалось, проблема с памятью, как и ожидалось. Контроллер, выступающий в качестве цели для кнопки, был освобожден. Это был корневой контроллер контроллера навигации, вид которого был добавлен непосредственно в окно. Мой код выглядел так:

MyController *myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];

Я предполагал, что myController будет сохранено, когда он будет передан в качестве корневого контроллера UINavigationController, но это оказалось неверным Решение состояло в том, чтобы назначить контроллер локальной переменной и выпустить его в dealloc. Интерфейс объекта, содержащего приведенный выше код, должен иметь:

...
@property (retain, nonatomic) MyController *myController;
...

И реализация:

self.myController = [[MyController new] autorelease];
UINavigationController* navController = 
    [[[UINavigationController alloc] initWithRootViewController:myController] autorelease];
[window addSubview:navController.view];

...

- (void)dealloc {
    [self.myController release];
    ...
    [super dealloc];
}
4 голосов
/ 17 марта 2013

Как отметил Гаммал и другие, это проблема с памятью. Это связано с тем, что ссылка на контроллер выходит из области видимости, и поэтому его память освобождается.

Если вы запускаете контроллер следующим образом:

MyController* controller = [[MyController alloc] initWithNibName:@"MyNib" bundle:nil];
[self.view addSubview:controller.view];

С вами все будет в порядке, если вы не используете ARC, поскольку ссылка не будет освобождена до тех пор, пока она не будет выпущена вручную. Так что у меня была эта проблема при обновлении проектов для использования ARC.

Если вы инициируете контроллер как автоматический выпуск или используете ARC, то, как только область действия, в которой находится контроллер, заканчивается, сборщик мусора освобождает контроллер, а события нажатия кнопки вызовут неправильные исключения памяти.

Способ решить эту проблему - сохранить ссылку активной, поэтому объявите ее в интерфейсе или, если ему нужен внешний доступ, в качестве свойства.

@interface MyParentController : UIView {
@private
    MyController* controller;
}

Затем добавьте это как:

controller = [[MyController alloc] initWithNibName:@"MyNib" bundle:nil];
[self.view addSubview:controller.view];

Если вы хотите, чтобы память собиралась позже, просто установите значение nil.

0 голосов
/ 15 января 2010

У меня есть мысль. Это случилось со мной много лет назад. В IB, ваше свойство View подключено к вашему представлению?

Однажды я отцепил их, и приложение так и не запустилось.

Кстати, хуже становится хуже, запустите проект снова. Не стоит этих головных болей, если вы уже проделали 2 минуты работы.

добро пожаловать в мир программирования для iPhone. Вам может понадобиться один из этих довольно скоро wigsmen.com; -)

...