这可以按预期工作:
// Return a sequence for photos
[[[[[[RACObserve(self, event.photos) filter:^BOOL(id value) { return value != nil ; }] flattenMap:^RACStream *(NSDictionary *photos)
{
NSLog(@"Got photos: %@" , photos) ;
return photos.rac_sequence.signal ;
}]
// Consider each photo
filter:^BOOL(NSDictionary *photoDescriptor)
{
NSLog(@"Descriptor: %@" , photoDescriptor) ;
return ((NSNumber *)photoDescriptor[@"primary"]).boolValue ;
}]
// Load the selected photo
map:^id(NSDictionary *selectedPhotoDescriptor)
{
NSLog(@"Photo URL: %@" , selectedPhotoDescriptor[@"url"]) ;
return [[AsyncImageFetcher imageAtURL:[NSURL URLWithString:selectedPhotoDescriptor[@"url"]] cache:YES] firstOrDefault:[UIImage imageNamed:@"detail_placeholder"]] ;
}]
// Deliver on main thread
deliverOn:RACScheduler.mainThreadScheduler]
subscribeNext:^(id x)
{
((UIImageView *)self.headerView).image = x ;
}] ;
这不;图像永远不会设置:
RAC( ((UIImageView *)self.headerView), image ) =
// Return a sequence for photos
[[[[[RACObserve(self, event.photos) filter:^BOOL(id value) { return value != nil ; }] flattenMap:^RACStream *(NSDictionary *photos)
{
NSLog(@"Got photos: %@" , photos) ;
return photos.rac_sequence.signal ;
}]
// Consider each photo
filter:^BOOL(NSDictionary *photoDescriptor)
{
NSLog(@"Descriptor: %@" , photoDescriptor) ;
return ((NSNumber *)photoDescriptor[@"primary"]).boolValue ;
}]
// Load the selected photo
map:^id(NSDictionary *selectedPhotoDescriptor)
{
NSLog(@"Photo URL: %@" , selectedPhotoDescriptor[@"url"]) ;
return [[AsyncImageFetcher imageAtURL:[NSURL URLWithString:selectedPhotoDescriptor[@"url"]] cache:YES] firstOrDefault:[UIImage imageNamed:@"detail_placeholder"]] ;
}]
// Deliver on main thread
deliverOn:RACScheduler.mainThreadScheduler] ;
为什么?
答案 0 :(得分:0)
这是适用的版本:
// When there's a new image, fetch it, and set the headerView (which by default is an UIImageView)
RAC( self, imageView.image ) =
// Return a sequence for photos
[[[[RACObserve(self, event.photos) ignore:nil] flattenMap:^RACStream *(NSDictionary *photos)
{
NSLog(@"Got photos: %@" , photos) ;
return photos.rac_sequence.signal ;
}]
// Consider each photo
filter:^BOOL(NSDictionary *photoDescriptor)
{
NSLog(@"Descriptor: %@" , photoDescriptor) ;
return ((NSNumber *)photoDescriptor[@"primary"]).boolValue ;
}]
// Load the selected photo
flattenMap:^RACStream *(NSDictionary *selectedPhotoDescriptor)
{
NSLog(@"selected photo desc: %@" , selectedPhotoDescriptor) ;
return [AsyncImageFetcher imageAtURL:[NSURL URLWithString:selectedPhotoDescriptor[@"url"]] cache:YES] ; // This will -deliverOn: the main thread
}] ;
请注意,AsyncImageFetcher
' s imageAtURL:cache:
会返回一个信号。
关于此解决方案的一些注意事项:
首先,我必须创建一个新的私有属性self.imageView
,除了返回self.headerView
之外什么都不做。其原因与RAC()
宏可以接受的论点有关。我开始怀疑我传递给RAC()
的参数导致了我的问题,所以我通过在上述私人财产中进行演员来简化它:
@synthesize imageView ;
- (UIImageView *) imageView
{
return (id) self.headerView ;
}
然后我尝试了:
RAC( self.imageView, image ) = …
但这并没有奏效。然后我尝试了
RAC( self, imageView.image ) = …
这很有效!那么我想,让我们摆脱self.imageView
并看看它是否适用于宏中的投射:
RAC( self, (((UIImageView *)headerView).image) ) = …
不幸的是,这会产生语法错误。
因此,利用铸造私有财产的解决方案可行,但感觉就像是一种解决方法。我接受了答案,因为它适用于我,但我仍然想知道是否可以在不创建(冗余)imageView属性的情况下执行此操作。
答案 1 :(得分:0)
我遇到过类似的问题,这是我的一些想法。
RAC(self.imageView, image)
绑定image
上的self.imageView
密钥路径,而RAC(self, imageView.image)
绑定imageView.image
上的self
密钥路径。这基本上意味着信号仅在第一种情况下绑定到image
的属性self.imageView
,而在第二种情况下仅绑定imageView.image
self
。在大多数情况下,差异可以忽略不计,但根据您所描述的,差异可能至关重要。如果绑定在创建imageView
之前发生,那么RAC(self, imageView.image)
只有self.imageView
可用,因为subscribeNext:
尚不存在。 (这很可能发生在imageView是一个IBOutlet并且绑定发生在viewDidLoad之前)。imageView
工作的原因可能是因为当Async信号接下来发送时(需要时间),{{1}}已经创建,因此您可以成功地将图像分配给它。