recursion块太早解除分配
我已经写了一个recursion块遵循这些准则:
NSMutableArray *groups = [NSMutableArray arrayWithArray:@[@"group1", @"group2", @"group3", @"group4"]; __block CommunicationCompletionHandler completion = [^{ [groups removeObjectAtIndex:0]; if ([groups count] > 0) { // This will send some information to the network, and calls the completion handler when it receives a response [mySocket saveGroup:groups[0] completion:completion]; } } copy]; // Removing copy here doesn't work either [mySocket saveGroup:groups[0] completion:completion];
在saveGroup:completion:
方法中,我将完成处理程序添加到数组中:
self.completionHandlers[SaveGroupCompletionHandlerKey] = [completion copy];
而当我收到一个响应,我调用下面的方法( key
是在这种情况下SaveGroupCompletionHandlerKey
):
- (void)performCompletionHandlerForKey:(NSString *)key { if (self.completionHandlers[key]) { ((CommunicationCompletionHandler)self.completionHandlers[key])(); [self.completionHandlers removeObjectForKey:key]; } }
问题是完成处理程序只被调用一次。 removeObjectForKey:
块取消分配。 如果我取消注释该行,一切工作正常。 我不知道如何数组有最后一个引用这个块,因为我添加一个copy
(我相信正在优化retain
)。
为了清楚起见,应用程序的stream程是:
- 通过networking发送第一组数据
- 接收回应
- 呼叫完成处理程序
- 在完成处理程序中,发送下一个组的数据(这是recursion部分)。
这里有谁能指出我做错了什么?
在-performCompletionHandlerForKey:
在执行完block 之后 ,你从你的字典中删除了完成处理程序,这意味着处理程序在一次运行后总是会从字典中移除。
而是将块存储在临时variables中,并在执行块之前将其从字典中删除。
顺便说一句,删除弱引用的build议是错误的。 由于您的代码现在写入,您的代码块将永远不会被释放。 典型的块recursion模式是这样的:
__weak __block MyBlock weakHandler; MyBlock handler = ^ { if (foo) { MyBlock strongHandler = weakHandler; [bar asyncOperationWithCompletion:strongHandler]; } }; weakHandler = handler; [bar asyncOperationWithCompletion:handler];
避免保留保留周期的常用方法是在定义块之前创build对象的弱引用,然后在块内创build一个强引用并将其设置为该弱引用。 这种方法经常用来避免强烈地捕捉块内的self
:
- (void)someMethod { __weak MyType *weakSelf = self; [self someMethodWithABlockArg:^{ MyType *strongSelf = weakSelf; [strongSelf someOtherMethod]; }]; }
块内创build的强引用可防止块在运行时释放对象。 当然,您可以对任何对象types执行相同的操作。
编辑2:看起来像[someBlock copy]
确实很好。 你有没有试过在代码上运行分析? 当它被引用到块内时,可能是completion
还没有初始化。
- 错误域= NSCocoaErrorDomain代码= 3840“没有值。”UserInfo = {NSDebugDescription =没有值。}
- 如何从常规的UIFont创build一个粗体UIFont?
- ios 7 dequeueReusableCellWithIdentifier:forIndexPath方法 – 是否需要registerClass方法
- 定制UIActionSheet
- NSNumber与NSString映射的NSDictionary是非属性列表对象
- 带拐angular半径和阴影的SWIFT UITableViewCell
- Tiianium studio 3.2.0在设备上的项目安装问题
- 错误“autorelease”不可用:在自动引用计数模式下不可用
- NSInteger和NSUInteger在混合的64位/ 32位环境中