You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C中for循环内responseCompletion的类型定义问题

问题解决与代码修正

核心问题分析

  1. Block类型声明错误:for-in循环中直接内联声明block类型的写法不符合Objective-C语法规范,需通过typedef简化后使用。
  2. 容器类型不匹配:loadingResponses声明为不可变NSDictionary,但后续要修改其中的数组,应使用NSMutableDictionary。
  3. 逻辑错误:网络请求的错误判断写反,error != nil时应处理错误而非加载图片;同时存在拼写错误completionhHandler。
  4. 数组初始化错误:字典中不存在对应key时,直接调用setArray会导致空指针崩溃,需先创建可变数组并存入字典。

修正后的完整代码

@interface ImageManager : NSObject

// 提前定义block类型,简化后续使用
typedef void(^ImageResponseBlock)(UIImage * _Nullable image);

// 改为NSMutableDictionary,支持动态修改内容
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSMutableArray<ImageResponseBlock> *> *loadingResponses;
@property (nonatomic, strong) NSCache *cache;
@property (nonatomic, strong) NSURLSession *session;

@end

@implementation ImageManager

- (instancetype)init {
    self = [super init];
    if (self) {
        _cache = [[NSCache alloc] init];
        _session = [NSURLSession sharedSession];
        _loadingResponses = [[NSMutableDictionary alloc] init];
    }
    return self;
}

-(void)fetchImage:(NSString *)urlString and:(ImageResponseBlock _Nonnull)completionHandler {
    // 修正拼写错误:completionhHandler -> completionHandler
    UIImage *image = [self.cache objectForKey:urlString];

    if (image != nil) {
        completionHandler(image);
        return;
    }

    NSMutableArray<ImageResponseBlock> *responseBlocks = self.loadingResponses[urlString];
    if (responseBlocks != nil) {
        [responseBlocks addObject:completionHandler];
        return;
    } else {
        // 先创建可变数组,再存入字典避免空指针
        responseBlocks = [[NSMutableArray alloc] initWithObjects:completionHandler, nil];
        self.loadingResponses[urlString] = responseBlocks;
    }

    NSURL *url = [[NSURL alloc] initWithString:urlString];
    [[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        UIImage *fetchedImage = nil;
        if (error == nil) { // 修正错误判断:无错误时才处理图片
            fetchedImage = [[UIImage alloc] initWithData:data];
            if (fetchedImage) {
                [self.cache setObject:fetchedImage forKey:urlString];
            }
        }

        // 遍历调用所有回调
        NSMutableArray<ImageResponseBlock> *blocks = self.loadingResponses[urlString];
        for (ImageResponseBlock responseCompletion in blocks) {
            responseCompletion(fetchedImage);
        }
        // 执行完回调后移除对应key,避免重复触发
        [self.loadingResponses removeObjectForKey:urlString];

        completionHandler(fetchedImage);

    }] resume];
}

@end

关键修正点说明

  • typedef的正确使用:提前定义ImageResponseBlock类型,后续所有需要用到该block的地方直接使用类型名,既避免重复复杂声明,也解决了for循环中的类型匹配问题。
  • 容器类型修正:将loadingResponses改为NSMutableDictionary,确保可以动态添加/修改其中的数组;数组初始化时先创建再存入字典,避免空指针崩溃。
  • 逻辑修复:修正网络请求的错误判断逻辑,确保只有请求成功时才加载图片;执行完所有回调后移除字典中的对应key,防止重复触发回调。
  • 拼写修正:将completionhHandler改为正确的completionHandler,避免编译错误。

内容的提问来源于stack exchange,提问作者bruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:47:44