在方法的实现签名中使用__weak
存储修饰符是否有效?特别是如果它不是方法的公共签名的一部分?例如:
- (UIView *)tableView:(__weak UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex
{
UIView *view = [ABHeaderView view];
view.actionBlock = ^{
[tableView doSomething];
}
// ...
return view;
}
这是否正确使用tableView
作为弱指针?或者我应该真正做__weak *weakTableView = tableView;
之类的事情并在块中使用weakTableView
吗?
我没有收到任何警告或错误,并且clang Static Analyzer不会发出任何警告。
答案 0 :(得分:1)
当涉及动态调度并覆盖(1)时,不要指望“动态”尊重存储修饰符或属性。
此方法在UIKit中正式声明。编译器在使用ARC时可能会出错,因为调用时它可能会使选择器与原始声明匹配。也就是说,你的声明对于UIKit是不可见的,如果UIKit也被编译为ARC,它将把它视为默认/强。如果声明不匹配,或者即使它们在客户端+调用者转换中不可见,也可能发生这种情况。
参数类型/属性不是选择器的一部分,也不适用于动态分派。 ARC应该在这里强大,并且调用者保存引用。这个具体的例子可能不会导致运行时错误,但这是一个值得怀疑的做法,我认为可以找到错误。我已经为属性in this answer证明了这一点。从根本上说,这是一个类似的概念。
使用动态objc调度的简单规则:在重新声明,定义和覆盖时始终匹配原始声明的签名。唯一可能的例外是C兼容的限定符,这些限定符不会改变签名(我见过的ObjC程序中非常 un 常见的做法)。
(1)从技术上讲,它不是覆盖,而是协议方法的实现。无论如何,信号应该是相同的。
答案 1 :(得分:0)
__strong
或__weak
存储修饰符是您内部实施的一部分。它们不会影响方法调用者生成的代码,所以我认为你现在很安全,将来也很有可能。
我确实认为它的风格很差,所以你建议将参考文献复制到弱引用似乎是一个很好的解决方案。