C および C++ では、一般的なメモリ プール アロケータを使用します。大量のメモリが割り当てられ、その中にすべての小さなオブジェクトが割り当てられます。完了すると、1 回の呼び出しですべてが解放されます。アプリのボトルネックを 10 倍高速化することができました。
質問は、Cocoa でこれを行うにはどうすればよいですか?
alloc メソッドを上書きするにはどうすればよいですか?
C および C++ では、一般的なメモリ プール アロケータを使用します。大量のメモリが割り当てられ、その中にすべての小さなオブジェクトが割り当てられます。完了すると、1 回の呼び出しですべてが解放されます。アプリのボトルネックを 10 倍高速化することができました。
質問は、Cocoa でこれを行うにはどうすればよいですか?
alloc メソッドを上書きするにはどうすればよいですか?
他のクラスメソッドをオーバーライドしalloc
たり、好きになったりすることができます。allocWithZone:
インスタンスにメモリを割り当て、isa
ポインタを設定する必要があります。このようなものが機能します:
void *memoryPool;
void *nextObject;
+ (id) alloc;
{
id result = (id)nextObject;
size_t instanceSize = class_getInstanceSize( self );
nextObject += instanceSize;
memset( result, 0, instanceSize );
result->isa = self;
return result;
}
+ (id) allocWithZone: (NSZone *) zone;
{
return nil;
}
- (void) dealloc; { /* do nothing */ }
これらのメソッドを実装するクラスのすべてのサブクラスは、のバッファに割り当てられmemoryPool
ます。バッファを割り当てるときnextObject
は、同じバッファに設定する必要があります。これらのオブジェクトを使い終わったら、を解放することですべてのオブジェクトの割り当てを解除できますmemoryPool
。
これはまだ完全ではないことに注意してください。dealloc
プールを解放する前にメソッドを呼び出すことができるように、割り当てられたすべてのオブジェクトの場所を追跡する必要があります。Deallocは、オブジェクトによって使用されているメモリを解放できませんが、他のリソースを解放する必要がある場合があります。
また、プールを解放する前に、プール内のオブジェクトへの参照がないことを確認する必要があります。
このようなプール内の任意のクラスのオブジェクトを割り当てることができるソリューションを探している場合は、運が悪いです。NSZone
withを使用するとallocWithZone:
、割り当て速度が向上する場合がありますが、ゾーン内のすべてのオブジェクトを一度に解放する方法はありません。
ただし、オブジェクトの割り当てがパフォーマンスの問題であることが確実な場合は、プロファイリング後にのみこれを実行する必要があります。多くの場合、そうではありません。