如何为块添加额外的参数

时间:2013-07-21 13:55:12

标签: objective-c objective-c-blocks anonymous-function mailcore

Mailcore有一个很酷的method下载附件并接受一个块作为参数来返回下载进度:

- (CTCoreAttachment *)fetchFullAttachmentWithProgress:(CTProgressBlock)block;

其中CTProgressBlock定义为

typedef void (^CTProgressBlock)(size_t curr, size_t max);

通常我会这样使用它:

//AttachmentDownloader.m
int fileNum = x; // explained later
CTCoreAttachment* fullAttachment = 
    [attachment fetchFullAttachmentWithProgress:^(size_t curr, size_t max) {
    NSLog(@"::: this is curr: %zu", curr);
    NSLog(@"::: this is max: %zu\n\n", max);
}];

问题是我的主UI类FileBucket.m调用了最后一个方法,而这个类依次为许多不同的UI元素提取许多附件。我希望这个回调方法向FileBucket.m报告这个进程所属的附件。所以换句话说,我想要的是:

// FileBucket.m
[AttachmentDownloader runMultiple:attachmentTree 
                     withProgress:^(size_t curr, size_t max, int fileNum) {
    NSLog(@"::: this is curr: %zu", curr);
    NSLog(@"::: this is max: %zu\n\n", max);
    NSLog(@"::: this progress belongs to element %d", fileNum);
}];

我知道这很难解释/说明..还有一件事:AttachmentDownloader.m知道这个进展的附件是什么......但它只是想把它传递给FileBucket.m 每次调用回调块。

2 个答案:

答案 0 :(得分:0)

我并不特别知道这个类,但通常任何块都“捕获”变量 在街区内使用。所以这应该“正常”:

int fileNum = x;
CTCoreAttachment* fullAttachment = 
    [attachment fetchFullAttachmentWithProgress:^(size_t curr, size_t max) {
    // ..
    NSLog(@"::: this progress belongs to element %d", fileNum);
}];

该块在创建块时捕获变量的值。

(如果使用fileNum修饰符声明__block,情况会略有不同, 但这可能与你的问题无关。)

答案 1 :(得分:0)

我想出来的方法是将其分为两个步骤:

  1. 通过委托
  2. 实现我想要的东西
  3. 将委托转换为基于块的方法。
  4. 由于这个问题很难通过英语解释,我认为最好通过示例代码解释:)

    委派解决方案:

    // AttachmentDownloader.m
    +(void)runMultiple:(NSDictionary *)attachmentTree 
          withDelegate:(id<AttachmentDownloaderDelegate>)delegate  {
        ..
    
        CTCoreAttachment* fullAttachment = 
           [attachment fetchFullAttachmentWithProgress:^(size_t curr, size_t max) {
                NSLog(@"::: this is curr: %zu", curr);
                NSLog(@"::: this is max: %zu\n\n", max);
                NSLog(@"::: this is attachment uid %@", [message uid]);
                [delegate deliverProgressWithInfo:@{@"uid":[message uid],
                                                    @"curr":[NSNumber numberWithInt:curr],
                                                    @"max":[NSNumber numberWithInt:max]}];
         }];
    
    
    // FileBucket.m
    [AttachmentDownloader runMultiple:attachmentTree withProgress:^(size_t curr, size_t max) {
        NSLog(@"::: this is curr: %zu", curr);
        NSLog(@"::: this is max: %zu\n\n", max);
    } withDelegate:self];
    
    // delegate method
    -(void)deliverProgressWithInfo:(NSDictionary *)dict {
        NSLog(@"filebucket: this is info being updated %@", dict);
    }
    

    阻止解决方案:

    // AttachmentDownloader.m
    +(void)runMultiple:(NSDictionary *)attachmentTree 
          withProgress:(void(^)(NSDictionary *))block {
        ..
    
        CTCoreAttachment* fullAttachment = 
            [attachment fetchFullAttachmentWithProgress:^(size_t curr, size_t max) {
            NSLog(@"::: this is curr: %zu", curr);
            NSLog(@"::: this is max: %zu\n\n", max);
            NSLog(@"::: this is attachment uid %@", [message uid]);
            block(@{@"uid":  [message uid],
                    @"curr": [NSNumber numberWithInt:curr],
                    @"max":  [NSNumber numberWithInt:max]});
        }];
    
    
    // FileBucket.m
    -(void)downloadSelectedAttachments {
        NSDictionary* attachmentTree = [self getAttachmentTree];
        [AttachmentDownloader runMultiple:attachmentTree withProgress:^(NSDictionary * dict) {
            NSLog(@"filebucket: this is info being updated %@", dict);
        }];
    }