我正在按照此处的指南创建自定义委托.它运行正常,但我在xcode中收到以下警告
DetailViewController.m:23:1:Autosynthesized属性'委托'将使用合成的实例变量'_delegate',而不是现有的实例变量'delegate'
任何人都可以建议如何摆脱警告
Nat*_*ler 39
处理这种情况最惯用的方法就是删除你的delegateivar声明.如果您使用的是delegateivar,则应使用隐式ivar _delegate.
为什么这样做?
从Xcode 4.4(LLVM编译器4.0)开始,如果@synthesize未对该属性明确使用该指令,则会自动为属性合成实例变量和访问器方法.作为Apple关于封装状态的文档
默认情况下,编译器会自动为您合成访问器方法,因此除了在类接口中使用@property声明属性之外,您无需执行任何操作.
用于属性的ivar(由自动合成的属性访问器方法获取和设置)被命名_<propertyName>(即,ivar的名称是以下划线为前缀的属性名称).
在这种情况下,属性名称是delegate,因此使用的是ivar _delegate.这已经在你的代码中发生了.当你调用-delegate和-setDelegate:,这伊娃_delegate将得到和设置.
但是,你也宣布了自己的伊娃delegate.当然,你明确声明(delegate)的ivar 不会被实例方法获取-delegate和设置,-setDelegate:因为自动合成的ivar(_delegate)被获取并设置.然而,(几乎总是 - 如果不是,你的代码是模棱两可的)你的意图是你的ivar delegate成为你的财产的访问者得到和设置的东西.幸运的是,编译器足够聪明,可以注意到你做了什么,这就是它发出这个警告的原因:
警告:autosynthesized属性'
delegate'将使用合成的实例变量'_delegate',而不是现有的实例变量'delegate'[-Wobjc-autosynthesis-property-ivar-name-match]
它告诉你,你的财产delegate将使用自动合成的ivar _delegate而不是你明确声明的ivar delegate.
因此,如果您只是删除您的delegateivar,编译器将停止发出此警告.如果您delegate直接使用ivar(而不是通过酒店),请_delegate改为开始使用.
此选项的一个小变化是显式声明属性_delegate的自动合成delegate正在创建的相同ivar().您可以通过替换来完成此操作
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> delegate
//...
}
@end
Run Code Online (Sandbox Code Playgroud)
同
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> _delegate
//...
}
@end
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为属性的自动合成将始终使用ivar,其名称是以下划线为前缀的属性名称.如果不存在这样的ivar,将生成ivar.如果确实存在,将使用它.
如果您希望您的属性的访问器设置并获取您的ivar,delegate您可以@synthesize向您的类添加一个指令' @implementation告诉编译器执行此操作:
@implementation TheClass
//...
@synthesize delegate = delegate;
//...
@end
Run Code Online (Sandbox Code Playgroud)
该行@synthesize delegate = delegate;告诉编译器delegate在属性的访问器中使用ivar (赋值的右手)delegate(赋值的左侧).
您也可以省略作业的右侧@synthesize并写入
@implementation TheClass
//...
@synthesize delegate;
//...
@end
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为具有手册的属性@synthesize没有明确指定由其访问器(例如@synthesize delegate;)获取和设置的ivar将使用与属性同名的ivar,而不是以下划线为前缀.这与向后兼容性有关.