在 Objective-C 中定义 completionHandler 的类型

Defining the type of a completionHandler in Objective-C

提问人:bruno 提问时间:8/11/2023 更新时间:8/11/2023 访问量:22

问:

在 for 周期中,我无法设法获得正确的类型。 试图用 typedef 替换它,但没有运气,只有更多的错误。responseCompletion

@interface ImageManager : NSObject

//typedef void(^responseBlock)(UIImage * _Nullable image);

@property (nonatomic, strong) NSDictionary<NSString *,NSMutableArray<void(^)(UIImage * _Nullable image)> *> *loadingResponses;
@end

-(void)fetchImage:(NSString *)urlString and:(void (^_Nonnull)(UIImage * _Nullable image))completionhHandler {

    UIImage *image = [self.cache objectForKey:urlString];

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

    if (self.loadingResponses[urlString] != nil) {
        [self.loadingResponses[urlString] addObject:completionhHandler];
        return;
    } else {
        [[self.loadingResponses objectForKey:urlString] setArray:[[NSMutableArray alloc] initWithObjects:completionhHandler, nil]];
    }

    NSURL *url = [[NSURL alloc] initWithString:urlString];
    [[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (error != nil) {
            UIImage *image = [[UIImage alloc] initWithData:data];
            [self.cache setObject:image forKey:urlString];
            completionhHandler(image);

            NSArray *array = [self.loadingResponses objectForKey:urlString];
            
            for ((void(^)(UIImage * _Nullable image) *responseCompletion) in array) {
                responseCompletion(image);
            }
        }

    }] resume];
}
objective-c xcode nsarray nsdictionary nsurl

评论


答:

1赞 HangarRash 8/11/2023 #1

你很好,虽然我会命名它,但不是.typedefResponseBlockresponseBlock

typedef void(^ResponseBlock)(UIImage * _Nullable image);

使用 时,请勿使用指针。ResponseBlock

我还建议更改为 an,以便您可以为其分配值。loadingResponsesNSMutableDictionary

下面是代码的更新版本:

界面:

typedef void(^ResponseBlock)(UIImage * _Nullable image);

@interface ImageManager : NSObject

@property (nonatomic, strong) NSMutableDictionary<NSString *, NSMutableArray<ResponseBlock> *> *loadingResponses;

@end

方法:

- (void)fetchImage:(NSString *)urlString and:(ResponseBlock)completionHandler {
    UIImage *image = [self.cache objectForKey:urlString];

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

    if (self.loadingResponses[urlString] != nil) {
        [self.loadingResponses[urlString] addObject:completionHandler];
        return;
    } else {
        self.loadingResponses[urlString] = [NSMutableArray arrayWithObject:completionHandler];
    }

    NSURL *url = [[NSURL alloc] initWithString:urlString];
    [[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error != nil) {
            UIImage *image = [[UIImage alloc] initWithData:data];
            [self.cache setObject:image forKey:urlString];
            completionHandler(image);

            NSArray *array = [self.loadingResponses objectForKey:urlString];

            for (ResponseBlock responseCompletion in array) {
                responseCompletion(image);
            }
        }
    }] resume];
}

我假设您在某处初始化为:loadingResponses

self.loadingResponses = [NSMutableDictionary dictionary];

如果出现错误,还需要调用完成处理程序。也许你的意思是:

    [[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        UIImage *image = nil;
        if (error != nil) {
            image = [[UIImage alloc] initWithData:data];
            [self.cache setObject:image forKey:urlString];
        }

        completionhHandler(image);

        NSArray<ResponseBlock> *array = self.loadingResponses[urlString];

        for (ResponseBlock responseCompletion in array) {
            responseCompletion(image);
        }
    }] resume];