在 Objective-C 中定义completionHandler 的类型

问题描述 投票:0回答:1

我无法在 for 循环中获得正确的

responseCompletion
类型。 尝试用 typedef 替换它,但没有成功,只有更多错误。

@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个回答
0
投票

你的

typedef
照原样就可以了,尽管我会把它命名为
ResponseBlock
,而不是
responseBlock

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

使用

ResponseBlock
时,请勿使用指针。

我还建议将

loadingResponses
更改为
NSMutableDictionary
,以便您可以为其赋值。

这是代码的更新版本:

界面:

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];
© www.soinside.com 2019 - 2024. All rights reserved.