3

これが状況です:Hockeyappとtestflightは時々私について不平を言います

「nil オブジェクトを挿入しようとしています」

変更可能な辞書/配列で。私は正しいことは常に nil をチェックすることであり、それが理にかなっているときはそうする..私たちのテスターはそれらのクラッシュをキャッチすることはできませんが、AppStore ユーザーは明らかにできる.

私の推測では、サーバーが返すべきではないときに NSNull を返すことがあります。したがって、巨大なプロジェクトのどこにでも nil のチェックを挿入しないように、テスター用に別のターゲットを作成し、コレクション クラスにメソッド スウィズリングを使用するというのが私の考えでした。オブジェクトが実際にnilinsertObject:atIndexswizzled_insertObject:atIndex場合、クラッシュする前に説明的なレポートをログに記録/表示します。

__NSPlaceholderDictionary問題は、または__NSArrayM (プライベート クラスでカテゴリを作成できないという理由だけで) にスウィズリングを使用できないことです。

基本的には、これらの厄介なまれなクラッシュを検出する方法についてアドバイスを求めています。私が念頭に置いている解決策の 1 つは、try-catch ブロックを使用することです。Objective-c ではそれらが高価であることはわかっているため、本番環境では使用せず、テスターのみに使用します。try-catcheただし、 -s で囲まれたメソッドは、 #ifdef-- s で囲まれ#endifており、コードの可読性がすべて失われます。だから私はよりエレガントなソリューションを探しています。ありがとう。

更新: スタック トレースは残念ながらあまり説明的ではありません。

Exception Type:  SIGABRT
Exception Codes: #0 at 0x3a378350
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'

Last Exception Backtrace:
0   CoreFoundation                      0x321522a3 <redacted> + 163
1   libobjc.A.dylib                     0x39e7a97f _objc_exception_throw + 31
2   CoreFoundation                      0x320a355f <redacted> + 135
3   CoreFoundation                      0x320da0d3 <redacted> + 51
....
4

6 に答える 6

3

クラッシュ メッセージ自体について注意すべき点が 1 つあります。

オブジェクト[#]からnilオブジェクトを挿入しようとする」は、インデックス[#](NSDictionaryリテラルリストを考えて)のキーまたは値のいずれかがnilであることを意味します。

辞書リテラルがあるとします

NSDictionary *person = @{@"first":firstName,@"last":lastName,@"email":email"};

次に、index[0] がリストの最初のペアになり、index[1] が 2 番目のペアになります。ペアのいずれかのエントリが nil の場合、対応するインデックスでこの例外がトリガーされます。

于 2015-02-11T13:38:03.693 に答える
1

私は3番目の答えに答えようとしましたが、ほとんどの場合に役立ちます. しかし、プロジェクト サポート フレームワーク 64 を使用していたときに、サード パーティの静的ライブラリが原因で、Ben が崩壊するという悲惨な事態に遭遇しました。Ben の折りたたみポイント CFDictionaryContainsKey。

CFDictionaryRef myDictionaryRef = ......
CFDictionaryContainsKey (myDictionaryRef, searchKey [0]). 

Ben が折りたたまれたとき、myDictionaryRef は nil です。いくつかのテストの後、問題が見つかりました。

interface __NSPlaceholderDictionary: NSMutableDictionary {
}
- (Id) initWithObjects: (const id *) arg1 forKeys: (const id *) arg2 count: (unsigned int) arg3;

答えを比較する

static id safe_initWithObjects (id self, SEL _cmd, const id objects [],   const id <NSCopying> keys [], NSUInteger count) {.....}

さまざまなタイプのパラメーターがベンの崩壊を引き起こしました。だから、私は正しい答えは

  #import <objc / runtime.h>
  #import <objc / message.h>
  static id safe_initWithObjects (id self, SEL _cmd, const id * objects, const id * keys, unsigned int count) {
      id orignialResult = nil;
     @try {
           orignialResult = objc_msgSend (self,selector (safe_initWithObjects: forKeys: count :), objects, keys, count);
          }
     @catch (NSException *exception) {
           NSLog(@"BUSTED!"); // put breakpoint here
         }

return orignialResult;
 }

  Class target = NSClassFromString (@ "__ NSPlaceholderDictionary");
  class_addMethod (target,selector (safe_initWithObjects: forKeys: count :), (IMP) & safe_initWithObjects, "@@: ** L");

 Method m1 = class_getInstanceMethod (target,selector (safe_initWithObjects: forKeys: count :));
 Method m2 = class_getInstanceMethod (target,selector (initWithObjects: forKeys: count :));
 method_exchangeImplementations (m1, m2);

回答提供者に感謝しますが、私は十分な評判 50 を持っているため、直接コメントすることはできません。投票していただければ幸いです。

于 2015-05-15T03:58:57.610 に答える
0

JSON を使用してサーバーからデータをフェッチすると仮定すると、JSON データのフィールドが null になる場合があるため、カバー後に NSNull を取得する場合があります。

したがって、私のアドバイスは、サーバーの「null」状況をチェックすることです。それが発生した場合は、失敗したメッセージを返しますが、不正な形式のデータをAPPに配信しないでください。

APP がそのようなデータを受信すると、APP はそれを処理する方法を知りません。もう異常です。例外をキャッチして異常なデータを無視することはできますが、私のやり方はソースから発生しないようにすることです。

于 2013-06-27T14:42:57.020 に答える
0

NSDictionaries を作成している場所を見て、オブジェクトが nil かどうかを確認するアサーション ステートメントをいくつか追加して、これを見つけました。

  1. 検索@{@" - 最新の構文を使用した辞書の作成の開始、またはNSDictionary
  2. Add NSAssert(object != nil, @"Your Object is is nil here"); オブジェクトを挿入する前に
  3. アプリを実行し、コンソールを確認して、対応するアサートを見つけて修正します。

    キャッチされていない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: 'Your Object is is nil here'

于 2014-06-09T22:57:03.863 に答える