代码之家  ›  专栏  ›  技术社区  ›  bruno vignesh

在Objective-C中定义completionHandler的类型

  •  0
  • bruno vignesh  · 技术社区  · 2 年前

    我拿不到 responseCompletion 在for循环的键入correct。 试图用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];
    }
    
    1 回复  |  直到 2 年前
        1
  •  1
  •   HangarRash    2 年前

    你的 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];
    }
    

    我假设你在某个地方初始化 加载响应 作为:

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