node.js EventEmitterに基づいてカテゴリを作成しようとしています。これは、多数のブロックを取り、それらを配列に弱く格納し、ブロックを作成するインスタンスの割り当てが解除されていない場合に後で実行できます (その場合、それらは配列から削除されます)。これは、古い未使用のブロックで配列を埋め続けないようにするためです。
問題は、ブロックを作成するインスタンスの割り当てが解除されても、ブロックがクラスによってコピーされたように見えるため、決して解放されないことです。
したがって、実装は次のようになります。
使用法
[object on:@"change" do:^(id slf, NSArray *args) {
NSLog(@"something changed");
}];
実装 (ここにあるWeakReference クラス、noaの好意による)
- (void)on:(NSString *)eventType do:(Callback)callback
{
NSMutableArray *callbacks = self.emitterEvents[eventType];
__weak Callback wcb = callback;
// Wrap the callback in NSValue subclass in order to reference it weakly
WeakReference *cbr = [WeakReference weakReferenceWithObject:wcb];
callbacks[callbacks.count] = cbr;
}
- (void)emit:(NSString *)eventType withArgs:(NSArray *)objArgs
{
NSInteger idx = 0;
NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
callbacks = (NSMutableArray *)callbacks;
for (WeakReference *cbv in callbacks) {
__weak id cb = [cbv nonretainedObjectValue];
if (cb) {
Callback callback = (Callback)cb;
__weak id slf = self;
callback(slf, objArgs);
} else {
[indices addIndex:idx];
}
idx++;
}
[callbacks removeObjectsAtIndexes:indices];
}
ブロックがその範囲を超えて使用されるとコピーされるという記事を読んだことがありますが、率直に言って、これらすべてのブロックのセマンティクスについて読むと、今、頭がくらくらします。
問題にアプローチするこの方法は可能ですか?