Shaun Chan
Shaun Chan

Reputation: 3

Objective C: Method to update UIImage

would you please consider the following method:

+(void)getGravatarFromEmail: (NSString *)email ofSize:(NSString *)size toImg:(UIImage *)myImg
{
    NSString *hash = [md5 getMD5Hash:email];  // external method to calculate md5 hash
    NSURL *gravatarUrl = [NSURL URLWithString:[NSString stringWithFormat:@"http://gravatar.com/avatar/%@?s=%@",hash,size]];

    ASIHTTPRequest *request = [[ASIHTTPRequest alloc]initWithURL:gravatarUrl];
    [request setCompletionBlock:^(void) {
        NSData *data = [request responseData];
        myImg = [UIImage imageWithData:data];  // ERROR HERE!!
    }];
    [request setDelegate:self];
    [request startAsynchronous];
}

This method simply makes an API call to Gravatar to retrieve an image. I would then update 'myImg' with the grabbed image.

However, I'm having errors trying to assign the image into 'myImg' as commented in the code. The error is:

Variable not assignable (missing __block type specifier)

Any clues for me?

Upvotes: 0

Views: 1103

Answers (1)

NSGod
NSGod

Reputation: 22948

+(void)getGravatarFromEmail:(NSString *)email ofSize:(NSString *)size 
           toImg:(UIImage *)myImg {
    NSString *hash = [md5 getMD5Hash:email];  // external method to calculate md5 hash
    NSURL *gravatarUrl = [NSURL URLWithString:[NSString
           stringWithFormat:@"http://gravatar.com/avatar/%@?s=%@",hash,size]];

    ASIHTTPRequest *request = [[ASIHTTPRequest alloc]initWithURL:gravatarUrl];

    __block UIImage *blockImage = myImg;

    [request setCompletionBlock:^(void) {
        NSData *data = [request responseData];
        blockImage = [UIImage imageWithData:data];  // ERROR HERE!!
    }];
    [request setDelegate:self];
    [request startAsynchronous];
}

I'm still a novice when it comes to blocks, but I believe the above modifications should allow your code to compile. That said, I'm not all that sure your method is using the block properly. First, the method is confusingly named (at least for most veterans). If it returns (void), and has get in the name, it seems as though you should have a pointer to a pointer to a UIImage like so:

+(void)getGravatarFromEmail:(NSString *)email ofSize:(NSString *)size 
               toImg:(UIImage **)myImg;

I believe if you're returning void, that's the only way you're going to be able to do anything with that myImg/blockImage.

Also, this is a class method, and you're setting the ASIHTTPRequests delegate to your class object, rather than an instance of your object?

Anyway, on to the error you were getting:

By default, I believe blocks have read-only access to variables. To be able to modify the myImg (or blockImage) variable from inside the block, you need to prefix the variable with the __block keyword. (That said, because of the reasons mentioned, above, I'm not all that sure what good being able to modify that variable from inside the block is).

Upvotes: 5

Related Questions