2014-04-14 199 views
1

我有我的實例變量聲明:訪問實例變量 - Objective-C的

@interface TimelineTableViewController() 

@property (strong, nonatomic) NSMutableArray *avatars; 

@end 

然後我的塊:

void UIImageFromURL(NSURL *URL, NSString *key, void(^imageBlock)(UIImage *image), void(^errorBlock)(void)) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
     NSData *data = [[NSData alloc] initWithContentsOfURL:URL]; 
     UIImage *image = [[UIImage alloc] initWithData:data]; 
     dispatch_async(dispatch_get_main_queue(), ^(void){ 
      if (image != nil) { 
       [self.avatars setObject:image forKey:key]; 
       NSLog(@"%@", self.avatars); 
       imageBlock(image); 
      } else { 
       errorBlock(); 
      } 
     }); 
    }); 
} 

我想要做的,就是高速緩存下載映像到實例數組以避免重新下載每個TableCell get的重新創建。但是,我得到的錯誤:

Use of undeclared identifier 'self' 

我打電話給我塊像這樣,如果這能幫助:

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    TweetCell *cell = (TweetCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    NSDictionary *tweetObject = _tweets[indexPath.row]; 
    NSDictionary *userObject = tweetObject[@"user"]; 

    NSString *avatarURL = userObject[@"profile_image_url"]; 
    avatarURL = [avatarURL stringByReplacingOccurrencesOfString:@"_normal" 
                withString:@""]; 
    NSURL *imageURL = [NSURL URLWithString:avatarURL]; 

    UIImageFromURL(imageURL, avatarURL, ^(UIImage *image) { 
     [cell.avatarImage setImage:image]; 
    }, ^{ 
     NSLog(@"Failed to fetch profile picture."); 
    }); 

    return cell; 
} 

回答

1

您可以UIImageFromURL(),而不是一個普通的C函數的實例方法, 那麼它可以訪問self

- (void)fetchImageFromURL:(NSURL *)URL key:(NSString *)key imageBlock:(void(^)(UIImage *image))imageBlock errorBlock:(void (^)(void))errorBlock 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
     NSData *data = [[NSData alloc] initWithContentsOfURL:URL]; 
     UIImage *image = [[UIImage alloc] initWithData:data]; 
     dispatch_async(dispatch_get_main_queue(), ^(void){ 
      if (image != nil) { 
       [self.avatars setObject:image forKey:key]; 
       NSLog(@"%@", self.avatars); 
       imageBlock(image); 
      } else { 
       errorBlock(); 
      } 
     }); 
    }); 
} 

,然後調用它像

[self fetchImageFromURL:imageURL key:avatarURL imageBlock:^(UIImage *image) { 
    [cell.avatarImage setImage:image]; 
} errorBlock:^{ 
    NSLog(@"Failed to fetch profile picture."); 
}]; 
2

你的塊之前,使用該行的代碼來修改你的self

// Weak self 
__weak MyViewController *weakSelf = self; 

並呼籲你的變量是這樣的:

void UIImageFromURL(NSURL *URL, NSString *key, void(^imageBlock)(UIImage *image), void(^errorBlock)(void)) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
     NSData *data = [[NSData alloc] initWithContentsOfURL:URL]; 
     UIImage *image = [[UIImage alloc] initWithData:data]; 
     dispatch_async(dispatch_get_main_queue(), ^(void){ 
      if (image != nil) { 
       [weakSelf.avatars setObject:image forKey:key]; 
       NSLog(@"%@", weakSelf.avatars); 
       imageBlock(image); 
      } else { 
       errorBlock(); 
      } 
     }); 
    }); 
} 

你可以參考here關於block的強有力的答案!

+0

嗯,我用這:'__weak TimelineTableViewController * weakSelf = self;'仍然可以使用未聲明的標識符self'。我使用了'TimelineTableViewController',因爲我的類是:'@interface TimelineTableViewController()',這是正確的嗎? – benhowdle89

1

你的代碼不是一個方法,而是一個簡單的C函數。因此,沒有「自我」。類方法以「+」開頭,實例方法以「 - 」開頭。