iPhone: вызов [NSBundle mainbundle] падает на устройстве, но не на симуляторе - PullRequest
1 голос
/ 03 февраля 2010

По сути, проблема именно в том, что написано в заголовке.

Мое приложение работает на симуляторе без сбоев. На самом деле предыдущая версия есть в магазине приложений. Я внес небольшие изменения тут и там, и внезапно он начал падать в очень странном месте.

Я использую [NSBundle mainBundle] resourcepath] в различных местах кода для доступа к plist-файлам, изображениям и т. Д. Первые несколько вызовов NSBundle mainBundle] совершенно нормальны, как и ожидалось, однако в какой-то момент он возвращает ...

-[NSBundle < null selector>]: unrecognized selector sent to instance 0x10a0e0

... и вылетает на устройстве. Вот точный фрагмент кода:

-(void) setImageName:(NSString *)s
{
 [imageName release];
 imageName = [s copy];
 NSLog(@"last line before crash"); 
 NSString *imagePath =[[NSBundle mainBundle] resourcePath];
 NSLog(@"Why would it crash before here???"); 

    imagePath = [imagePath stringByAppendingString:imageName];
    imageUI = [[UIImage alloc] initWithContentsOfFile:imagePath];
    [self setNeedsDisplay];
}

Чтобы проверить, действительно ли этот вызов является проблемой, я сохранил resourcePath в строку при первом вызове [NSBundle mainbundle] в проекте (первые несколько вызовов были совершенно нормальными, как я уже говорил выше) и использовал это resourcePath строка везде, где мне было нужно [NSbundle mainbundle] и вуаля! нет сбоев / утечек, ничего ...

Я полностью сбит с толку .. Почему этот вызов может привести к сбою моего приложения на устройстве, но не на симуляторе?

Редактировать: используя ...

NSArray *array = [NSBundle allBundles];
NSBundle *bundle = [array objectAtIndex:0];
NSString *imagePath = [bundle bundlePath];

... вместо [[NSBundle mainBundle] resourcePath] тоже работает. Я предполагаю, что каким-то образом я делаю что-то, влияющее только на этот конкретный звонок.

Редактировать 2 : Вот обратная трассировка, когда я устанавливаю точку останова в - [NSObject doesNotRecognizeSelector:]:

#0  0x30e27b98 in -[NSObject doesNotRecognizeSelector:]
#1  0x30dacb18 in ___forwarding___
#2  0x30da3840 in __forwarding_prep_0___
#3  0x0000bcfe in -[CustomTableViewCell setImageName:] at CustomTableViewCell.m:93
#4  0x0000499e in -[RootTableViewController tableView:willDisplayCell:forRowAtIndexPath:] at RootTableViewController.m:469
#5  0x3364d5d0 in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:]
#6  0x3364cde0 in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:]
#7  0x335f832c in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow]
#8  0x335f6514 in -[UITableView layoutSubviews]
#9  0x335f22d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#10 0x32bac1c0 in -[CALayer layoutSublayers]
#11 0x32babedc in CALayerLayoutIfNeeded
#12 0x32bab844 in CA::Context::commit_transaction
#13 0x32bab474 in CA::Transaction::commit
#14 0x32bb35dc in CA::Transaction::observer_callback
#15 0x30da1830 in __CFRunLoopDoObservers
#16 0x30de9346 in CFRunLoopRunSpecific
#17 0x30de8c1e in CFRunLoopRunInMode
#18 0x332e7374 in GSEventRunModal
#19 0x335adc30 in -[UIApplication _run]
#20 0x335ac230 in UIApplicationMain

... Где # 3 - CustomTableViewCell.m: 93 - это NSString * imagePath = [[NSBundle mainBundle] resourcePath]; в той части кода, которую я разместил выше.

Ответы [ 6 ]

4 голосов
/ 03 февраля 2010

Включите NSZombieEnabled, и вы увидите, где на самом деле проблема.

1 голос
/ 04 февраля 2010

Вы должны быть в состоянии сделать [NSBundle mainBundle] почти в любое время. Как насчет того, чтобы разбросать его по своему коду, чтобы он перехватывал его в первый раз, мы надеемся, что он близок к чему-то, что нарушает управление памятью (т. Е. Происходит повреждение памяти), поскольку состояния St3fan могут быть проблемой.

1 голос
/ 04 февраля 2010

Сбой на устройстве, но не на симуляторе (и наоборот) обычно вызывается скомпилированной библиотекой / структурой, которая соответствует одной аппаратной платформе, но не другой. Поскольку симулятор работает на Intel, а устройство на руке, это вызывает странные сбои. Отметьте все, что вы могли добавить, особенно то, что вы недавно не компилировали.

Ошибка -[NSBundle < null selector>]: unrecognized selector sent to instance 0x10a0e0 предполагает, что по какой-то причине класс NSBundle "забыл", что у него есть метод mainBundle. Обратите внимание, что это селектор, который является нулевым, а не объект, как мы могли бы ожидать в ошибке, связанной с памятью. Это говорит о каком-то высоком уровне коррупции где-то.

Я бы поставил следующий журнал перед любыми звонками на [NSBundle mainBundle];

NSLog(@"responds to selector mainBundle=%@",[NSBundle respondsToSelector:@selector(mainBundle)]?@"YES":@"NO");

Это скажет вам, если он действительно теряет селектор mainBundle.

Edit01:

Спасибо за ваш ответ. Похоже на то Nsbundle заявляет, что может ответить mainbundle: "отвечает на селектор mainBundle = YES ", непосредственно перед аварийный вызов [NSBundle mainBundle]

Хммм, сбой должен быть достаточно серьезным, чтобы вызвать неправильный возврат кода ошибки. Это говорит о том, что проблема может быть в строках непосредственно перед или после вызова mainBundle.

Учитывая, что сбой происходит в CustomTableViewCell, я предполагаю, что это проблема в кончике. У вас есть подкласс UITableViewCell, определенный в кончике? У вас есть изображение, определенное в перо? Какой это тип файла? Возникает ли та же ошибка с другим изображением или другим пером?

Я думаю, что ключ к разгадке в том, что он работает на симуляторе, но не на устройстве. Вы должны искать вещи, которые будут вести себя по-разному в зависимости от оборудования.

У вас, конечно, тут сложный вопрос.

1 голос
/ 03 февраля 2010

Имейте в виду, что жесткие пути кодирования в вашем документе не очень хорошая идея.Ваш путь меняется (обычно с каждой сборкой).Что касается вашего сбоя, трудно понять, не увидев больше кода.Но взгляните на это предложение:

вместо

 [imagePath stringByAppendingString:imageName]; 

, которое вы должны использовать

 [imagePath stringByAppendingPathComponent:imageName];

stringByAppendingPathComponent особенно подходит для работы с путями и именами файлов.

1 голос
/ 03 февраля 2010

По сути, проблема именно в том, что говорится в названии. - Нет, это не такЯ могу гарантировать вам, что [NSBundle mainBundle] является не причиной сбоя.Сбой - это признак того, что вы делаете неправильно в другой части вашего кода.Как например плохое управление памятью.

0 голосов
/ 03 февраля 2010

Одна из возможных проблем заключается в том, что если по какой-либо причине вам случится передать одно и то же изображение imageName дважды, вы отпустите его, прежде чем сохранить его. Возможно, вы захотите изменить первые две строки на:

if (imageName != s) {
    [imageName release];
    imageName = [s retain]; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...