我正在按照此处的指南创建自定义委托。它运行良好,但我在 xcode 中收到以下警告
DetailViewController.m:23:1:自动合成的属性“delegate”将使用合成的实例变量“_delegate”,而不是现有的实例变量“delegate”
谁能建议如何摆脱警告
我正在按照此处的指南创建自定义委托。它运行良好,但我在 xcode 中收到以下警告
DetailViewController.m:23:1:自动合成的属性“delegate”将使用合成的实例变量“_delegate”,而不是现有的实例变量“delegate”
谁能建议如何摆脱警告
处理这种情况最惯用的方法就是删除您的delegate
ivar 声明。如果您使用的是delegate
ivar,则应使用隐式 ivar _delegate
。
为什么这行得通?
从Xcode 4.4 (LLVM Compiler 4.0)开始,如果@synthesize
指令没有显式用于该属性,则实例变量和访问器方法会自动为该属性合成。正如Apple 关于封装的文档所述
默认情况下,编译器会自动为您合成 [...] 访问器方法,因此您无需执行任何操作,只需在类接口中使用 @property 声明属性。
用于属性的 ivar(由自动合成的属性访问器方法获取和设置)被命名_<propertyName>
(即 ivar 的名称是带有下划线前缀的属性名称)。
在这种情况下,属性名称是delegate
,所以使用的 ivar 是_delegate
。这已经在您的代码中发生了。当您调用-delegate
and时,将获取并设置 -setDelegate:
此 ivar 。_delegate
但是,您还声明了自己的 ivar delegate
。当然,delegate
实例方法不会获取和设置您显式声明的 ivar ( ) -delegate
,因为正在获取和设置-setDelegate:
自动合成的 ivar ( )。_delegate
但是,(几乎总是——如果不是,您的代码是模棱两可的)您的意图是让您的 ivardelegate
成为您的属性的访问者将获取和设置的东西。幸运的是,编译器足够聪明,可以注意到您所做的事情,这就是它发出此警告的原因:
警告:自动合成的属性“
delegate
”将使用合成的实例变量“_delegate
”,而不是现有的实例变量“delegate
”[-Wobjc-autosynthesis-property-ivar-name-match
]
它告诉您,您的属性delegate
将使用自动合成_delegate
的 ivar,而不是您明确声明的 ivar delegate
,.
因此,如果您只是删除您的delegate
ivar,编译器将停止发出此警告。如果您delegate
直接使用 ivar(而不是通过属性),请开始使用_delegate
。
此选项的一个细微变化是显式声明与属性_delegate
的自动综合delegate
正在创建的相同 ivar ( )。您可以通过更换来做到这一点
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> delegate
//...
}
@end
和
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> _delegate
//...
}
@end
这是有效的,因为属性的自动合成将始终使用一个 ivar,其名称是带有下划线前缀的属性名称。如果不存在这样的 ivar,则将生成 ivar。如果它确实存在,它将被使用。
相反,如果您希望设置属性的访问器并获取您的 ivar delegate
,则可以向您的类添加@synthesize
指令@implementation
以告诉编译器这样做:
@implementation TheClass
//...
@synthesize delegate = delegate;
//...
@end
该行@synthesize delegate = delegate;
告诉编译器delegate
在属性delegate
(赋值的左侧)的访问器中使用 ivar(赋值的右侧)。
您也可以省略作业的右侧@synthesize
,只写
@implementation TheClass
//...
@synthesize delegate;
//...
@end
这是有效的,因为具有手册的属性@synthesize
未明确指定要由其访问器(例如@synthesize delegate;
)获取和设置的 ivar 将使用与属性同名的 ivar,而不是以下划线前缀。这与向后兼容性有关。
还有另一种方法,这个方法对我有用:
@property (nonatomic, unsafe_unretained) id <MyDelegate> delegate;
然后,您可以将其添加到实现中而不会出错:
@synthesize delegate;
另外:这是符合 ARC 的。