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

シミュレータではなくデバイスでのクラッシュ(およびその逆)は、通常、一方のハードウェアプラットフォームでは準拠しているが、もう一方では準拠していないコンパイル済みライブラリ/フレームワークが原因で発生します。シミュレーターはIntelで実行され、デバイスはアームで実行されるため、これにより奇妙なクラッシュが発生します。追加した可能性のあるもの、特に最近コンパイルしなかったものを確認してください。

このエラー-[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は、[NSBundle mainBundle]へのクラッシュ呼び出しの直前に、mainbundleに応答できると述べているようです。「selectormainBundle=YESに応答します」。

うーん、クラッシュは間違ったエラーコードを返すのに十分悪いはずです。これは、mainBundleの呼び出しの直前または直後の行に問題がある可能性があることを示しています。

CustomTableViewCellでクラッシュが発生することを考えると、ペン先の問題であると推測します。ペン先で定義されたUITableViewCellのサブクラスがありますか?ペン先に画像が定義されていますか?それはどのファイルタイプですか?別の画像または別のペン先で同じエラーが発生しますか?

重要な手がかりは、シミュレーターでは機能するが、デバイスでは機能しないことだと思います。ハードウェアに基づいて動作が異なるものを探す必要があります。

あなたは確かにここで難しいものを持っています。

于 2010-02-04T00:05:01.500 に答える
1

[NSBundle mainBundle]いつでもできるはずです。St3fan が問題である可能性があると述べているように、メモリ管理を壊すもの (メモリ破損の発生) に近いことを願っています。

于 2010-02-04T13:05:55.760 に答える
1

ドキュメントにパス文字列をハード コーディングすることはお勧めできません。パスが変更されます (通常はビルドごとに)。クラッシュに関する限り、さらにコードを見ずに知ることは困難です。しかし、この提案を見てください:

それ以外の

 [imagePath stringByAppendingString:imageName]; 

あなたが使用する必要があります

 [imagePath stringByAppendingPathComponent:imageName];

stringByAppendingPathComponent は、特にパスとファイル名の処理に適しています。

于 2010-02-03T18:56:17.500 に答える
1

基本的に、問題はまさにタイトルが言っていることです。- いいえそうではありません。それがクラッシュの理由で[NSBundle mainBundle]ないことを保証できます。クラッシュは、コードの別の部分で間違ったことをしている兆候です。たとえば、メモリ管理が悪いなどです。

于 2010-02-03T18:26:32.793 に答える
0

考えられる問題の 1 つは、何らかの理由で同じ imageName を 2 回渡した場合、それを保持する前に解放してしまうことです。最初の 2 行を次のように変更できます。

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