ios - 无法使用 block 在 UITableViewCell 中设置 UIButton 标题

标签 ios objective-c uitableview block

我在自定义UITableViewCell中有一个UIButton,当我按下按钮时,它会使用AFNetworking将数据发布到我的服务器,在成功 block 我设置了一个新的按钮标题,但它不起作用。 在 CutomTableViewCell 中,我使用协议(protocol),以便可以响应按钮单击:

@implementation SubjectReplyCell

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

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

然后我实现委托(delegate)并将数据发布到服务器:

@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) {

    }];
}

但是如果我将标题设置在 block 之外,它会很好地工作:

- (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 默认使用主队列来处理失败和完成 block ,因此您无需担心自己调用主线程来更改 UI。 See this answer

您需要使用__block如果要修改 block 内的对象,请使用关键字(即两个下划线)。使用__block提前告诉编译器您计划改变 block 内的对象,因此以不同的方式对待该对象以保留更改。

所以这个:

__weak typeof(SubjectReplyCell) *weakCell = cell;

应该是这样的:

__block typeof(SubjectReplyCell) *weakCell = cell;

编辑: 您不需要使用 __weak在您的单元格上,因为修改此 block 中的单元格不应创建引用循环。在这种情况下,您的单元格将保留在完成 block 中,但单元格不会同时保留 block 本身,因此这两个不会创建保留循环。

您需要使用__weak如果正在使用的两个对象有可能导致保留循环,例如当您在 block 中捕获 self 并且该 block 也被 self 捕获时。 Here's another answer for some more clarity

关于ios - 无法使用 block 在 UITableViewCell 中设置 UIButton 标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31705079/

相关文章:

ios - 如何将用户的 blob id 中的照片提供给对话框?

ios - Realm AddOrUpdate 一个带有对象列表的对象覆盖后面的对象

ios - iOS OpenGL ES 3.0 上缺少 GL_GEOMETRY_SHADER

iphone - 奇怪的赋值错误

ios - Xcode/iOS : Unit Tests, 方案和配置

iOS:使用设置切换 PHPhotoLibrary 权限

ios - 如何更改 objective-c 中的字体样式和颜色或操作表?

ios - UICollectionViewController 中的 Flipped CollectionView 被 Navigation Controller 覆盖

ios - 有没有办法使用 RubyMotion 在 UITableViewController 中重新加载数据?

ios - 如何让 NSURLConnection.sendAsynchronousRequest 在 UITableView 初始化之前执行