Mazyod
Mazyod

Reputation: 22569

Copy an instance variable into an Objective-C Block

I have the following code:

- (void)downloadPressed:(id)sender {
    [_download startDownloadWithParser:^id(NSData *rawData) {
        NSString* downloadName = [[_download url] lastPathComponent];

        // ... more code
    }];

    [self reloadView];
}

This code is located inside a UITableViewCell, and as we all know, the reuse mechanism should be taken very special note of..

My Question, Clean & Simple:

If I add the following line of code after the block:

_download = nil;

The _download variable inside the block also gets nil'd! I would like it to get a copy instead, how?

Upvotes: 4

Views: 1733

Answers (2)

Martin R
Martin R

Reputation: 540075

_download in the block is interpreted as self->_download, therefore the block captures self and not download.

This explains why setting _download = nil affects the block, the solution has already been given.

Upvotes: 3

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727047

If you would like your block to get a copy of your ivar, make a local variable from it, and use that local inside your block instead of the ivar:

-(void)downloadPressed:(id)sender {
    MyDownload *tmp = _download; // Make an independent pointer
    [tmp startDownloadWithParser:^id(NSData *rawData) { // Use the local
        NSString* downloadName = [[tmp url] lastPathComponent];
        // ... more code
    }];
    [self reloadView];
}

The block will capture the value of that local variable at the time the block object is created, making all subsequent changes to _download invisible to your block.

Upvotes: 7

Related Questions