objective-c – 自动合成属性’delegate’将使用合成实例变量’_delegate’,而不是现有的实例变量’delegate’

我正在按照指南here创建一个自定义委托。它运行正常,但我在xcode中收到以下警告

DetailViewController.m:23:1: Autosynthesized property ‘delegate’ will
use synthesized instance variable ‘_delegate’, not existing instance
variable ‘delegate’

任何人都可以建议如何摆脱警告

最佳答案
处理这种情况的最惯用方法只是删除您的代表ivar声明。如果您正在使用代理ivar,则应使用隐式ivar _delegate。

为什么这个工作?

Xcode 4.4 (LLVM Compiler 4.0)开始,如果没有明确地为该属性使用@synthesize指令,那么将为属性自动合成实例变量和访问器方法。正如Apple’s documentation on encapsulation所述

By default, […] accessor methods are synthesized automatically for you by the compiler, so you don’t need to do anything other than declare the property using @property in the class interface.

用于属性(由自动合成的属性访问器方法获取并设置)的ivar命名为_< propertyName> (即ivar的名称是该属性的名称,前缀为下划线)。

在这种情况下,属性名称是委托,所以使用的ivar是_delegate。您的代码中已经出现这种情况。当你调用-delegate和-setDelegate:时,这个ivar _delegate将被获取并设置。

但是,您也已经宣布了自己的ivar代表。当然,您明确声明(委托)的ivar将不会被实例方法-delegate和-setDelegate所设置,因为自动合成的ivar(_delegate)被获取和设置。但是,(几乎总是 – 如果不是,你的代码是模糊的)你的意图是你的ivar代表是你的财产的访问者得到和设置的东西。幸运的是,编译器很聪明,可以注意到你做了什么,这就是为什么它发出这个警告:

warning: autosynthesized property ‘delegate‘ will use synthesized instance variable ‘_delegate‘, not existing instance variable ‘delegate‘ [-Wobjc-autosynthesis-property-ivar-name-match]

它告诉你,你的属性委托将使用自动合成的ivar _delegate而不是您显式声明,委托的ivar。

所以如果你只是删除你的委托ivar,编译器就会停止发出这个警告。如果您直接使用代理ivar(不是通过属性),请开始使用_delegate。

此选项的一个细微变化是明确声明与委托属性的自动合成正在创建的相同的ivar(_delegate)。你可以通过更换来做到这一点

@interface TheClass : TheSuperclass
{
    //...
    id<TheDelegateProtocol> delegate
    //...
}
@end

@interface TheClass : TheSuperclass
{
    //...
    id<TheDelegateProtocol> _delegate
    //...
}
@end

这是因为自动合成属性将始终使用名称为属性前缀为下划线的名称的ivar。如果没有这样的ivar存在,就会产生静脉。如果它存在,它将被使用。

如果相反,您希望您的属性的访问者设置并获取您的ivar代理,您可以向您的类“@implementation”添加一个@synthesize指令,以通知编译器仅执行以下操作:

@implementation TheClass
//...
@synthesize delegate = delegate;
//...
@end

行@synthesize delegate = delegate;告诉编译器在属性委托(分配的左侧)的访问器中使用ivar代理(作业的右侧)。

您也可以省略@synthesize作业的右侧,只需写入

@implementation TheClass
//...
@synthesize delegate;
//...
@end

这是因为具有手动@synthesize的属性没有明确指定要由其访问器(例如@synthesize delegate;)获取和设置的ivar将使用与该属性具有相同名称的ivar,而不是前缀为下划线。这与向后兼容性有关。

转载注明原文:objective-c – 自动合成属性’delegate’将使用合成实例变量’_delegate’,而不是现有的实例变量’delegate’ - 代码日志