3

オブジェクトsomeObjectとがあるとしNSMutableArray *someArrayます。配列内にあるかどうかはわかりませんsomeObjectが、配列内にある場合は削除したいと思います。次の 2 つのオプションがあります。

ケース 1:

if([someArray indexOfObject:someObject] != NSNotFound)
   [someArray removeObject:someObject];

ケース 2:

[someArray removeObject:someObject];

ケース 2 では、オブジェクトが配列に存在しない場合、何も起こりません。私の質問は、ケース 1 では配列を検索して存在するかどうかを確認する必要があるため、ケース 2 の方が効率的removeObject:ですか?

4

4 に答える 4

6

しかし、removeObject: はそのオブジェクトの配列を再度検索すると思いますか?

そうですね、そうしなければなりません。コレクション内のオブジェクトを検索せずに見つける方法はありません。*ドキュメントでは次のようにさえ述べられています。

このメソッドは、 を使用indexOfObject:して一致を見つけ、 を使用してそれらを削除しますremoveObjectAtIndex:。[...] 配列に が含まれていない場合anObject、メソッドは効果がありません (内容を検索するオーバーヘッドは発生しますが)。

もちろん、フレームワークを模倣して、removeObjectAtIndex:必要に応じて検索の直後に自分自身を使用することもできます。


NSArray* sは配列ではないため、これは実際よりも高速です (最悪の場合、O(N) ではなく O(log(N))) 。

于 2012-04-30T19:58:52.153 に答える
5

配列は、検索したすべてのオブジェクトを覚えているわけではありません。何らかの理由で、削除する前にそこにあったかどうかを知る必要がある場合は、二重検索を回避できます

NSUInteger tempIndex = [someArray indexOfObject:someObject];
if (tempIndex != NSNotFound)
   [someArray removeObjectAtIndex:tempIndex]
else
   //in case it wasn't found...
于 2012-04-30T20:03:28.920 に答える
2

NSMutableArray、オブジェクトを削除するように求められたときに、オブジェクトを検索したことを「覚えていません」。したがって、呼び出しindexOfObject後に続く呼び出しはremoveObject、単に単独で呼び出すよりも必然的に多くの作業を必要とremoveObjectします。

于 2012-04-30T19:58:49.143 に答える
0

ドキュメントに記載されているように、ケース2を使用してremoveObjectを呼び出すだけです

このメソッドは、indexOfObject: を使用して一致を見つけ、removeObjectAtIndex: を使用してそれらを削除します。したがって、一致は isEqual: メッセージに対するオブジェクトの応答に基づいて決定されます。配列に anObject が含まれていない場合、メソッドは効果がありません (ただし、内容を検索するオーバーヘッドが発生します)。

したがって、基本的に2つのコード例は同じですが、配列はあなたがチェックしたことを知らないため、あなたの後に別のチェックを行う可能性があるため、余分なCPU時間が無駄になります。しかし、正直なところ、私は今このような例についてあまり考えず、アプリを開発し、最適化に関しては、すべての CPU 時間を占有しているものを見て、このようなケースが実際にかかり始めたら調整します。あなたのCPU時間を上げてください。

于 2012-05-01T02:27:38.010 に答える