0

Mailcore有一个很酷的方法,它可以下载附件并接受一个块作为参数来返回下载进度:

- (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 每次调用回调块时将其传回。

4

2 回答 2

0

我不具体知道那个类,但一般来说,任何块“捕获”块内使用的变量。所以这应该“正常工作”:

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

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

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

于 2013-07-21T14:10:21.973 回答
0

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

  1. 通过委托实现我想要的
  2. 将委托转换为基于块的方法。

由于这个问题很难用英语解释,我认为最好用示例代码来解释:)

委托解决方案:

// 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);
    }];
}
于 2013-07-22T05:59:17.583 回答