简体   繁体   中英

can't set UIButton title in UITableViewCell with block

I have a UIButton in a custom UITableViewCell , when I press the button it will post data to my server using AFNetworking ,in the success block I set a new button title, but it doesn't work. In CutomTableViewCell I use a protocol so I can respond button click:

@implementation SubjectReplyCell

- (IBAction)btnReplyPressed:(UIButton *)sender {

    if (self.delegate && [self.delegate respondsToSelector:@selector(postData:atIndex:)]) {
        [self.delegate postData:self atIndex:sender.tag];
    }
}
@end

Then I implementation the delegate and post data to server:

@implementation BBSDetailsController
- (void)postData:(SubjectReplyCell *)cell atIndex:(NSInteger)idx {
    urlString = [API_HOST stringByAppendingString:BBS_PRAISE_OPPOSITION];
    __weak typeof(SubjectReplyCell) *weakCell = cell;

    [requestManager POST:urlString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([responseObject[@"returnode"] isEqualToString:@"success"]) {
            //it doesn't work
            [weakCell.btnReply setTitle:@"newTitle" forState:UIControlStateNormal];
            [weakCell setNeedsLayout];
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];
}

But if I set title out of the block it work well:

- (void)postData:(SubjectReplyCell *)cell atIndex:(NSInteger)idx {
    urlString = [API_HOST stringByAppendingString:BBS_PRAISE_OPPOSITION];

    //it work
    [cell.btnReply setTitle:@"newTitle" forState:UIControlStateNormal];

    [requestManager POST:urlString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([responseObject[@"returnode"] isEqualToString:@"success"]) {

        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];
}

AFNetworking uses the main queue by default for failure and completion blocks, so you don't need to worry about invoking the main thread for UI changes yourself. See this answer

You need to use the __block keyword (that's two underscores) if you want to modify an object inside a block. Using __block tells the compiler ahead of time that you plan on mutating the object inside a block, so treat this object differently in order to keep the changes.

So this:

__weak typeof(SubjectReplyCell) *weakCell = cell;

should be this:

__block typeof(SubjectReplyCell) *weakCell = cell;

edit: You shouldn't need to use __weak on your cell because modifying your cell in this block should not create a reference loop. In this case your cell will be retained in the completion block, but the cell does not also retain the block itself, so these two will not create a retain cycle.

You need to use __weak if the two objects in play have a chance of causing a retain cycle, like when you capture self in a block and that block is also captured by self. Here's another answer for some more clarity

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM