-subscribeNext:有效,但RAC()没有

时间:2014-03-17 18:53:36

标签: ios objective-c reactive-cocoa

这可以按预期工作:

        // 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] ;

为什么?

2 个答案:

答案 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)

我遇到过类似的问题,这是我的一些想法。

  1. 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之前)。
  2. imageView工作的原因可能是因为当Async信号接下来发送时(需要时间),{{1}}已经创建,因此您可以成功地将图像分配给它。
相关问题