1

これは自問自答です。他の人を助けるためにそれをそこに置く。

アプリで非常に興味深いクラッシュが発生しました。私がやりたかったことは、モデルの静的メソッドとして返されるソート コンパレータを定義することでした。

たとえば、私のモデルが車で、名前で並べ替えたい場合は、次のようになりますCar.m

+ (NSComparator)nameSortAscendingComparator {
    NSComparator nameSortAscendingComparator = ^NSComparisonResult(id obj1, id obj2) {
        NSString *a = [(Car *)obj1 name];
        NSString *b = [(Car *)obj2 name] ;
        return [a compare:b] ;
    };
}

呼び出しコードは次のようになります。

    NSComparator comparator = [Car nameSortAscendingComparator];
   _sortedCars = [cars sortedArrayUsingComparator:comparator];

これを実行すると、本当の赤いニシンの例外が発生しました。実際には、次のように見えました。

Xcode のメイン デバッグ ウィンドウのスクリーンショット

ブレークポイントが停止した場合:

Thread 1, Queue : com.apple.main-thread
#0  0x0231fcbc in _objc_empty_vtable ()
#1  0x0280c70a in __56-[NSArray sortedArrayFromRange:options:usingComparator:]_block_invoke_0 ()
#2  0x0273f07d in __CFSimpleMergeSort ()
#3  0x0273f124 in __CFSimpleMergeSort ()
#4  0x0273f008 in CFSortIndexes ()
#5  0x0277ad71 in -[NSArray sortedArrayFromRange:options:usingComparator:] ()
#6  0x0279a2b5 in -[NSArray sortedArrayUsingComparator:] ()

それは私をあらゆる種類の庭の小道に導きました。ブロックは、静的変数として、または静的メソッドを介してアクセスできませんか? おそらくinitialize、問題を引き起こしているのは、これをすべて実行していたのでしょうか?

4

1 に答える 1

1

与えられたのは、私が見つけられなかったコンパイラの警告でした。いつものように、コンパイラの警告が蓄積されるのを許すことは致命的です。それらは、実際の問題が発生したときにそれを覆い隠します。

この場合、次のとおりでした。

Control reaches end of non-void function

はい、私のnameSortAscendingComparatorメソッドは実際には何も返しませんでした。どっ!問題が解決しました。

私が興味を持っているのは、あいまいな「そのようなファイルはありません」というメッセージの背後にある説明でしょうか? _objc_empty_vtable は言うまでもありません。vtable についてもっと知りたいのですが、それは非 void 関数のクラッシュとの関係です。

于 2013-09-17T13:09:31.840 に答える