-1

画面のサイズである CGRect で始まるアプリを作成しています。ユーザーが CGRect の内部に触れると、2 つの CGRect に分割されます。作成された新しい CGRect の内部に触れると、これはうまく機能しますが、rectangleArray に追加された最新のものではない CGRect 内に触れると、アプリがクラッシュし、sigabrt と表示されます。

touchesBegan のコードは次のとおりです。blockPoint は画面がタッチされたポイントです

for (NSValue *val in rectangleArray){
    CGRect rectangle = [val CGRectValue];
    if (CGRectContainsPoint(rectangle, blockPoint)) {
        CGRect newRectangle;
        CGRect addRectangle;
        if (!inLandscape) {
            newRectangle = CGRectMake(rectangle.origin.x, rectangle.origin.y, rectangle.size.width, blockPoint.y - rectangle.origin.y);
            addRectangle = CGRectMake(rectangle.origin.x, blockPoint.y, rectangle.size.width, rectangle.size.height - (blockPoint.y - rectangle.origin.y));

        }
        else {
            newRectangle = CGRectMake(rectangle.origin.x, rectangle.origin.y, blockPoint.x - rectangle.origin.x, rectangle.size.height);
            addRectangle = CGRectMake(blockPoint.x, rectangle.origin.y, rectangle.size.width - (blockPoint.x - rectangle.origin.x), rectangle.size.height);
        }
        [rectangleArray replaceObjectAtIndex:[rectangleArray indexOfObject:val] withObject:[NSValue valueWithCGRect:newRectangle]];
        [rectangleArray addObject:[NSValue valueWithCGRect:addRectangle]];
    }
}

なぜこれがクラッシュするのですか?

4

2 に答える 2

1

配列を列挙しながら (「replaceObjectAtIndex:」を使用して) 配列を変更しようとしています (コードの先頭にある「for ループ」)。これは例外です。コンソール ログに次のように表示されます。

キャッチされない例外 'NSGenericException' が原因でアプリを終了しています。理由: '*** 列挙中にコレクションが変更されました。

代わりにできることは、最初に列挙し、次に変更したいオブジェクトを特定し、それらを別のコレクション クラス (NSSet または別の NSArray) に格納し、最後に収集した項目を元の配列に適用することです。または、最初の配列のコピーを作成し、そのコピーを列挙して元の配列に変更を加えるという別の可能性もあります。

于 2011-11-05T22:12:18.917 に答える
0

コードで以前にこの問題が発生しましたが、initorinitWith....メソッドで配列を作成したと推測できますよね?

initメソッドでコード (つまり、Interface Builder からの UI コントロールではない) を使用してプロパティを適切に作成するには、常にプロパティを保持します。

要するに、

myNSMutableArray = [[NSMutableArray alloc] initWith....];

する必要があります

myNSMutableArray = [[[NSMutableArray alloc] initWith....] retain];

このように、initメソッドが終了しても、保持カウントによりmyNSMutableArray、システムはオブジェクトを解放/解放できなくなります。

または、(保持)方法でプロパティを宣言するため、使用できます

self.myNSMutableArray = [[NSMutableArray alloc] initWith...];

アクセサーを使用すると、保持が行われます。

于 2011-11-05T22:23:21.277 に答える