0

宣言および合成された可変配列プロパティがあります。

@property (nonatomic, strong) NSMutableArray *arrayOfTasks;

同じプロパティにKVCコレクション アクセサーを使用しています。また、この KVC コレクション アクセサー メソッドを次のように内部的に呼び出す他のメソッドもあります。

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
}

いくつかの変更を行い、特定の条件が満たされた場合にのみオブジェクトを配列に追加する必要があったため、このチェックが指定されたメソッドに確実に適用されるように、-insertObject KVC Collection アクセサー メソッドに以下を含めました。

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
    if ([inTask isOperatable])
    {
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
    }
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
}

-addObjectINArrayOfTasksメソッドをトリガーするたびに、-isOperatable条件がブール値の NO を返すと、スタック トレースがまったくない状態でアプリがクラッシュします。(スタック トレースはアプリケーションの main() にあります)。それが言うのは、「空の配列エラーの範囲を超えたインデックス0」です。

この理由を理解していません。まだ配列にアクセスしようとしていないため、フレームワークがインデックス 0 に要素がないと不平を言う機会を与えていません。さらに、配列項目のカウントを行っています。配列からオブジェクトにアクセスする前に、どこでもチェックしてください。境界外のインデックスにアクセスして要素にアクセスしようとすると、同じ時点でアプリがクラッシュし、境界外のインデックスにアクセスしようとした場所を正確に知らせてくれます。それは単純で簡単な修正でした。

さて、相互検証のために、次のようにコードを少し変更しましたが、うまくいくようです。

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
    if ([inTask isOperatable])
    {
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
    }
}

機能していてクラッシュしないこのアプローチを進めることができますが、私の懸念は次のとおりです。

  1. 指定されたメソッドに同じチェックを追加することは、将来、他のプログラマーが別の場所から指定されたメソッドを呼び出したい場合に、追加の利点になります。

  2. 条件チェックに基づいて KVC コレクション アクセサーの配列にオブジェクトを挿入しないと、最初のケースでアプリがクラッシュするのはなぜですか?

ご意見ありがとうございます。

ラージ

4

1 に答える 1

2

表示されているクラッシュは、アレイよりも内部の KVC 動作に関連している可能性が高いと思います。これが、使用可能なスタック トレースが表示されない理由である可能性があります。Xcode で例外ブレークポイントを有効にしましたか?

-insertObject:in<Key>AtIndex:KVCは基本的に、指定されたインデックス(おそらくあなたの場合は0)に新しいオブジェクトを挿入することを期待しています。オブジェクトが挿入されたと想定しているため、指定されたインデックスでオブジェクトのデータ構造 (NSMutableArray) をキューに入れることでアクセスできるようになります。条件が NO になった場合、このオブジェクトを挿入できません。つまり、KVO が提供されたインデックスを使用してクエリを実行しようとすると、インデックス範囲外の例外が発生する可能性があります。

投稿した 2 番目のコードでは、挿入が不要な場合に KVC コレクション アクセサーを呼び出さないことで、このエラーを回避しています。

誰かがこれらのメソッドを誤って使用する可能性を最小限に抑えたい場合-addObjectInArrayOfTasks:は、公開ヘッダーだけで公開してください。さらに、これを文書化できます。-insertObject:in<Key>AtIndex:int 自体でアクセスできないことを絶対に確実にしたいNSAssert場合は、メソッドが から呼び出されたかどうかをチェックするを追加できます-addObjectInArrayOfTasks:

于 2012-11-09T07:47:56.077 に答える