objective-c - 访问 block 内的实例变量 - Objective-C

标签 objective-c objective-c-blocks

我有我的实例变量声明:

@interface TimelineTableViewController ()

@property (strong, nonatomic) NSMutableArray *avatars;

@end

然后是我的 block :

void UIImageFromURL(NSURL *URL, NSString *key, void(^imageBlock)(UIImage *image), void(^errorBlock)(void)) {
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
        NSData  *data  = [[NSData alloc] initWithContentsOfURL:URL];
        UIImage *image = [[UIImage alloc] initWithData:data];
        dispatch_async( dispatch_get_main_queue(), ^(void){
            if (image != nil) {
                [self.avatars setObject:image forKey:key];
                NSLog(@"%@", self.avatars);
                imageBlock( image );
            } else {
                errorBlock();
            }
        });
    });
}

我想做的是将下载的图像缓存到实例数组中,以避免重新下载每个重新创建的 TableCell。但是,我收到错误:

Use of undeclared identifier 'self'

我这样称呼我的 block ,如果有帮助的话:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TweetCell *cell = (TweetCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSDictionary *tweetObject = _tweets[indexPath.row];
    NSDictionary *userObject = tweetObject[@"user"];

    NSString *avatarURL = userObject[@"profile_image_url"];
    avatarURL = [avatarURL stringByReplacingOccurrencesOfString:@"_normal"
                                                     withString:@""];
    NSURL *imageURL = [NSURL URLWithString:avatarURL];

    UIImageFromURL(imageURL, avatarURL, ^(UIImage *image) {
        [cell.avatarImage setImage:image];
    }, ^{
        NSLog(@"Failed to fetch profile picture.");
    });

    return cell;
}

最佳答案

在你的 block 之前,使用这行代码来修改你的self:

// Weak self
__weak MyViewController *weakSelf = self;

并像这样调用你的变量:

void UIImageFromURL(NSURL *URL, NSString *key, void(^imageBlock)(UIImage *image), void(^errorBlock)(void)) {
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
        NSData  *data  = [[NSData alloc] initWithContentsOfURL:URL];
        UIImage *image = [[UIImage alloc] initWithData:data];
        dispatch_async( dispatch_get_main_queue(), ^(void){
            if (image != nil) {
                [weakSelf.avatars setObject:image forKey:key];
                NSLog(@"%@", weakSelf.avatars);
                imageBlock( image );
            } else {
                errorBlock();
            }
        });
    });
}

您可以引用here关于block的有力答案!

关于objective-c - 访问 block 内的实例变量 - Objective-C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23054997/

相关文章:

objective-c - 如何在 Swift 中传递 Raw Json 来发布请求?

ios - 为什么 NULL 需要用 block 进行类型转换?

ios - Objective-C 命名 block 的参数

ios - 从 swift 调用 objective-C typedef block

ios - ViewDidLoad 的随机图像生成器

ios - 使用动态字典创建可扩展 TableView

ios - xcode 检查是否有 aobjectAtIndex 或检查数组长度

ios - 在 iOS 中对 pdf 文档进行数字签名

objective-c - 在 swift/objective-c 中以多个参数作为参数的 block

ios - 直接从 UIButton 操作添加 subview ,而无需调用方法