在Objective-C中定义completionHandler的类型。

huangapple go评论77阅读模式
英文:

Defining the type of a completionHandler in Objective-C

问题

I can't manage to get the responseCompletion type correct, at the for cycle.
Tried to replace it with typedef, but got no luck, only more errors.

@interface ImageManager : NSObject

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

-(void)fetchImage:(NSString *)urlString and:(void (^_Nonnull)(UIImage * _Nullable image))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 objectForKey:urlString] setArray:[[NSMutableArray alloc] initWithObjects:completionHandler, 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];
        completionHandler(image);

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

        for (void(^responseCompletion)(UIImage * _Nullable image) in array) {
            responseCompletion(image);
        }
    }

}] resume];

}

英文:

I can't manage to get the responseCompletion type correct, at the for cycle.
Tried to replace it with typedef, but got no luck, only more errors.

@interface ImageManager : NSObject

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

@property (nonatomic, strong) NSDictionary&lt;NSString *,NSMutableArray&lt;void(^)(UIImage * _Nullable image)&gt; *&gt; *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

得分: 1

Your typedef is fine as-is though I would name it ResponseBlock, not responseBlock.

typedef不需要修改,但我建议将其命名为ResponseBlock,而不是responseBlock

When you use ResponseBlock, don't use a pointer.

当你使用ResponseBlock时,不要使用指针。

I also suggest changing loadingResponses to be an NSMutableDictionary so you can assign values to it.

我还建议将loadingResponses 更改为NSMutableDictionary,以便你可以为其分配值。

Here's an updated version of your code:

以下是你的代码的更新版本:

The interface:

接口部分:

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

@interface ImageManager : NSObject

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

@end

The method:

方法部分:

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

I'm assuming somewhere you initialize loadingResponses as:

我假设你在某处初始化loadingResponses如下:

self.loadingResponses = [NSMutableDictionary dictionary];

You also need to call the completion handler if there is an error. Perhaps you mean to do:

如果发生错误,你还需要调用完成处理程序。也许你想这样做:

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

    completionHandler(image);

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

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

Your typedef is fine as-is though I would name it ResponseBlock, not responseBlock.

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

When you use ResponseBlock, don't use a pointer.

I also suggest changing loadingResponses to be an NSMutableDictionary so you can assign values to it.

Here's an updated version of your code:

The interface:

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

@interface ImageManager : NSObject

@property (nonatomic, strong) NSMutableDictionary&lt;NSString *, NSMutableArray&lt;ResponseBlock&gt; *&gt; *loadingResponses;

@end

The method:

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

I'm assuming somewhere you initialize loadingResponses as:

self.loadingResponses = [NSMutableDictionary dictionary];

You also need to call the completion handler if there is an error. Perhaps you mean to do:

    [[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&lt;ResponseBlock&gt; *array = self.loadingResponses[urlString];

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

huangapple
  • 本文由 发表于 2023年8月11日 01:52:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878213.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定