基本上问题正是标题所说的。
我的应用程序在模拟器上运行顺畅,没有任何崩溃。 事实上,以前的版本是在应用程序商店。我在这里和那里做了一些小改动,然后它突然在一个非常奇怪的地方崩溃了。
我在代码中的不同位置使用[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];在我上面发布的代码部分。
答案 0 :(得分:4)
启用NSZombieEnabled,您将看到问题的确切位置。
答案 1 :(得分:1)
基本上问题正是标题所说的。 - 不,不是。我可以向您保证[NSBundle mainBundle]
不崩溃的原因。崩溃是您在代码的另一部分中出错的症状。例如糟糕的内存管理。
答案 2 :(得分:1)
请注意,将路径字符串硬编码到文档中并不是一个好主意。您的路径发生了变化(通常每个构建版本)。就崩溃而言,如果没有看到更多代码,很难知道。但请看一下这个建议:
而不是
[imagePath stringByAppendingString:imageName];
你应该使用
[imagePath stringByAppendingPathComponent:imageName];
stringByAppendingPathComponent特别适合处理路径和文件名。
答案 3 :(得分:1)
设备崩溃但模拟器崩溃(反之亦然)通常是由编译的库/框架引起的,该库/框架是针对一个硬件平台而不是另一个硬件平台而编译的。由于模拟器在英特尔和手臂上的设备上运行,因此会导致奇怪的崩溃。检查您可能添加的任何内容,尤其是您最近未编译的任何内容。
错误-[NSBundle < null selector>]: unrecognized selector sent to instance 0x10a0e0
表明,无论出于何种原因NSBundle
类已“遗忘”,它都有mainBundle
方法。请注意,它是选择器,它是null,而不是我们在内存相关错误中所期望的对象。这表明某些地方存在一些高层腐败。
我会在调用[NSBundle mainBundle];
NSLog(@"responds to selector mainBundle=%@",[NSBundle respondsToSelector:@selector(mainBundle)]?@"YES":@"NO");
这会告诉你它是否真的突然失去了mainBundle
选择器。
<强> Edit01:强>
感谢您的回答。它似乎 Nsbundle说它可以回应 mainbundle:“响应选择器 mainBundle = YES“,就在之前 崩溃调用[NSBundle mainBundle]
嗯,崩溃必须足够严重,导致错误的错误代码返回。这表明问题可能出现在调用mainBundle之前或之后的行中。
鉴于在CustomTableViewCell中发生了崩溃,我猜它会在笔尖中出现问题。你有一个在笔尖中定义的UITableViewCell的子类吗?你有在笔尖定义的图像吗?它是什么文件类型的?不同的图像或不同的笔尖是否会出现相同的错误?
我认为关键线索是它可以在模拟器上运行但不在设备上运行。您需要根据硬件查找行为不同的内容。
你在这里肯定很难受。
答案 4 :(得分:1)
你应该能够随时做[NSBundle mainBundle]
。如何将它分散在你的代码中以便在它第一次中断时捕获,希望接近破坏内存管理的东西(即发生内存损坏),因为St3fan状态可能是问题。
答案 5 :(得分:0)
一个可能的问题是,如果由于某种原因,您碰巧两次传递相同的imageName,您将在保留之前释放它。您可能希望将前两行更改为:
if (imageName != s) {
[imageName release];
imageName = [s retain];
}