1

基本上问题正是标题所说的。

我的应用程序在模拟器上运行顺畅,没有任何崩溃。事实上,以前的版本在应用商店。我在这里和那里做了一些小改动,突然它开始在一个非常奇怪的地方崩溃。

[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]; 在我上面发布的代码部分。

4

6 回答 6

4

打开 NSZombieEnabled,你会发现问题出在哪里。

于 2010-02-03T18:36:04.220 回答
1

基本上问题正是标题所说的。- 不它不是。我可以向你保证,这不是[NSBundle mainBundle]崩溃的原因。崩溃是您在代码的另一部分中做错了什么的症状。例如糟糕的内存管理。

于 2010-02-03T18:26:32.793 回答
1

请注意,将路径字符串硬编码到文档中并不是一个好主意。您的路径会发生变化(通常在每次构建时)。就您的崩溃而言,如果不查看更多代码,就很难知道。但是看看这个建议:

代替

 [imagePath stringByAppendingString:imageName]; 

你应该使用

 [imagePath stringByAppendingPathComponent:imageName];

stringByAppendingPathComponent 特别适合处理路径和文件名。

于 2010-02-03T18:56:17.500 回答
1

设备上的崩溃而不是模拟器上的崩溃(反之亦然)通常是由编译的库/框架引起的,该库/框架针对一个硬件平台而不是另一个硬件平台编译。由于模拟器在 intel 上运行,而设备在 arm 上运行,这会导致奇怪的崩溃。检查您可能添加的任何内容,尤其是您最近未编译的任何内容。

该错误-[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选择器。

编辑01:

感谢您的回答。似乎 Nsbundle 声明它可以响应 mainbundle:“响应选择器 mainBundle = YES”,就在对 [NSBundle mainBundle] 的崩溃调用之前

嗯,崩溃一定严重到导致错误的错误代码返回。这表明问题可能出在调用 mainBundle 之前或之后的行中。

鉴于崩溃发生在 CustomTableViewCell 中,我猜这是笔尖的问题。您是否在笔尖中定义了 UITableViewCell 的子类?你有在笔尖中定义的图像吗?它是什么文件类型?不同的图像或不同的笔尖是否会出现相同的错误?

我确实认为关键线索是它可以在模拟器上运行,但不能在设备上运行。您需要根据硬件寻找行为不同的东西。

你肯定在这里遇到了困难。

于 2010-02-04T00:05:01.500 回答
1

你应该可以[NSBundle mainBundle]在任何时候做。如何将它分散在您的代码中以在第一次中断时捕获它,希望接近于破坏内存管理(即发生内存损坏)的东西,正如 St3fan 所说的那样,这可能是问题所在。

于 2010-02-04T13:05:55.760 回答
0

一个可能的问题是,如果由于某种原因,您碰巧两次传递了相同的 imageName,您将在保留它之前释放它。您可能希望将前两行更改为:

if (imageName != s) {
    [imageName release];
    imageName = [s retain]; 
}
于 2010-02-03T18:41:57.500 回答