【发布时间】:2013-04-15 00:14:04
【问题描述】:
我正在尝试基于 node.js EventEmitter 编写一个类别,它可以采用多个块,将它们弱存储在一个数组中,如果创建块的实例没有被释放,则稍后执行它们(在这种情况下,它们将从数组中删除)。这是为了不继续用旧的、未使用的块填充数组。
问题是这些块似乎是由类复制的,因此从未释放,即使创建块的实例已被释放。
所以实现看起来像这样;
用法
[object on:@"change" do:^(id slf, NSArray *args) {
NSLog(@"something changed");
}];
实现(WeakReference 类发现 here,由 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];
}
我读到了一些关于 blocks being copied 的内容,但坦率地说,阅读所有这些块语义现在有点让我头晕目眩。
这种解决问题的方法是否可行?
【问题讨论】:
标签: objective-c cocoa events objective-c-blocks