我正在尝试基于 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];
}
我读过一些关于块在超出其范围时被复制的内容,但坦率地说,阅读所有这些块语义现在有点让我头晕目眩。
这种解决问题的方法甚至可能吗?