objective-c - 在实现中使用 __weak 修改参数的存储

标签 objective-c memory-management automatic-ref-counting objective-c-blocks

在方法的实现签名中使用 __weak 存储修饰符是否有效?特别是如果它不是方法的公共(public)签名的一部分?例如:

- (UIView *)tableView:(__weak UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex
{
    UIView *view = [ABHeaderView view];
    view.actionBlock = ^{
        [tableView doSomething];
    }
    // ...
    return view;
}

这是否正确使用 tableView 作为弱指针?或者我真的应该做类似 __weak *weakTableView = tableView; 的事情并在 block 中使用 weakTableView 吗?

我没有收到任何警告或错误,clang 静态分析器也没有抛出任何警告。

最佳答案

当涉及动态调度和覆盖时,不要指望存储修饰符或属性会“动态地”得到尊重 (1)。

这个方法是在 UIKit 中正式声明的。编译器在使用 ARC 时可能会出错,因为它可能会在调用时将选择器与原始声明匹配。也就是说,您的声明对 UIKit 不可见,如果它也被编译为 ARC,UIKit 会将其视为默认/强。如果声明不匹配,或者即使它们在客户端+调用方翻译中不可见,也可能会发生这种情况。

参数类型/属性不是选择器的一部分,也不应用于动态调度。 ARC 应该在这里假定为强,并且调用者 持有引用。这个具体示例可能不会导致运行时错误,但这是一个有问题的做法,我认为可以找到错误。我已经为属性 in this answer 证明了这一点.从根本上说,这是一个类似的概念。

动态对象分派(dispatch)的简单规则:在重新声明、定义和覆盖时始终匹配原始声明的签名。唯一的异常(exception)可能是 C 兼容的限定符,它不会改变签名(这是我见过的 ObjC 程序中非常的常见做法)。

(1) 从技术上讲,它不是覆盖,而是协议(protocol)方法的实现。无论如何,签名应该是相同的。

关于objective-c - 在实现中使用 __weak 修改参数的存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10187993/

相关文章:

ios - 如果检查两个文本字段背后的逻辑

c++ - QStandardItemModel 中项目的重新分配

java - 我的 Swing 应用程序是否分配了冗余对象?

c++ - C++中正确删除一个成员数组

c++ - 如何使用 ARC 使 C++ 模板适用于 Objective C 类型?

objective-c - 在 Objective-C 中,将 block 中的弱点分配给强点是什么意思?

ios - 在不更改界面的情况下更新ios中的分段控件

ios - 向其发送消息时会保留自身

ios - 使用自动布局 (VFL) 增加自定义单元格按钮的高度

ios - ARC - 如何管理那些需要 __unsafe_unretained 的属性?