[我正在使用RAC,尤其是Colin Eberhardt的Twitter搜索example,遇到了我无法向自己解释的崩溃。
这里是我创建的sample project,用于说明问题并以此为基础。
应用程序使用具有可重复使用单元格的UITableView
;每个单元格上都有一个UIImageView
,其图像是通过某些URL下载的。还定义了一个用于将图像下载到后台队列中的信号:
- (RACSignal *)signalForLoadingImage:(NSString *)imageURLString
{
RACScheduler *scheduler = [RACScheduler
schedulerWithPriority:RACSchedulerPriorityBackground];
return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURLString]];
UIImage *image = [UIImage imageWithData:data];
[subscriber sendNext:image];
[subscriber sendCompleted];
return nil;
}] subscribeOn:scheduler];
}
在cellForRowAtIndexPath:
中,我通过image
宏将加载信号绑定到图像视图的RAC
属性:
RAC(cell.kittenImageView, image) =
[[[self signalForLoadingImage:self.imageURLs[indexPath.row]]
takeUntil:cell.rac_prepareForReuseSignal] // Crashes on multiple binding assertion!
deliverOn:[RACScheduler mainThreadScheduler]]; // Swap these two lines to 'fix'
现在,当我运行该应用程序并开始上下滚动表视图时,该应用程序将崩溃并显示断言消息:
Signal <RACDynamicSignal: 0x7f9110485470> name: is already bound to key path "image" on object <UIImageView: <...>>, adding signal <RACDynamicSignal: 0x7f9110454510> name: is undefined behavior
但是,如果我先将图像加载信号包装到deliverOn:
中,然后再包装到takeUntil:
中,则>单元重用就可以了:
RAC(cell.kittenImageView, image) = [[[self signalForLoadingImage:self.imageURLs[indexPath.row]] deliverOn:[RACScheduler mainThreadScheduler]] takeUntil:cell.rac_prepareForReuseSignal]; // No issue
所以我的问题是:
image
属性,但是我完全不确定它是如何发生的。感谢您阅读这里:-)
我正在使用RAC,尤其是Colin Eberhardt的Twitter搜索示例,遇到了我无法向自己解释的崩溃。这是我创建的示例项目...
我尚未确认,但这是可能的解释: