自动合成的属性"delegate"将使用合成的实例变量"_delegate",而不是现有的实例变量"delegate" [英] Autosynthesized property 'delegate' will use synthesized instance variable '_delegate', not existing instance variable 'delegate'

查看:78
本文介绍了自动合成的属性"delegate"将使用合成的实例变量"_delegate",而不是现有的实例变量"delegate"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在此处指南中创建自定义委托.它运行正常,但我在xcode中收到以下警告

I'm following the guide here to create a custom delegate. It runs fine but I get the following warning in xcode

DetailViewController.m:23:1:自动合成的属性委托"将 使用综合实例变量"_delegate",而不是现有实例 变量委托"

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

任何人都可以建议如何消除警告

Can anyone advise how to get rid of the warning

推荐答案

处理这种情况的最惯用的方法就是删除您的delegate ivar声明.如果您使用的是delegate ivar,则应改用隐式ivar _delegate.

The most idiomatic way to handle this situation is simply to remove your delegate ivar declaration. If you were using your delegate ivar, you should use the implicit ivar _delegate instead.

为什么这样做?

Xcode 4.4(LLVM编译器4.0)起,实例变量和访问器方法如果@synthesize指令未明确用于该属性,则自动为该属性合成.如 Apple的封装文档所述

As of Xcode 4.4 (LLVM Compiler 4.0), instance variables and accessor methods are synthesized automatically for a property if the @synthesize directive is not used explicitly for that property. As Apple's documentation on encapsulation states

默认情况下,[...]访问器方法由编译器自动为您合成,因此,除了在类接口中使用@property声明属性外,您无需做任何其他事情.

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的名称是带有下划线的属性名称).

The ivar that is used for a property (which is gotten and set by the automatically synthesized property accessor methods) is named _<propertyName> (i.e. the ivar's name is the property's name prefixed with an underscore).

在这种情况下,属性名称为delegate,因此所使用的ivar为_delegate.这已经在您的代码中发生了.当您调用-delegate-setDelegate:时,将获取并设置此ivar _delegate.

In this case the property name is delegate, so the the ivar that is used is _delegate. This is already happening in your code. When you call -delegate and -setDelegate:, this ivar _delegate will be gotten and set.

但是,您还声明了自己的ivar delegate.当然,实例方法-delegate-setDelegate:不会获取和设置您显式声明的ivar(delegate),因为将获取并设置自动综合的ivar(_delegate).但是,(几乎总是-如果不是这样,则您的代码是模棱两可的),您的意图是让ivar delegate成为属性的访问者可以获取和设置的东西.幸运的是,编译器足够聪明,可以注意到您所做的事情,这就是为什么它发出此警告的原因:

However, you've also declared your own ivar delegate. Of course, the ivar you explicitly declared (delegate) will not be gotten and set by the instance methods -delegate and -setDelegate: since the automatically synthesized ivar (_delegate) is being gotten and set. However, (almost always--if it wasn't, your code is ambiguous) your intent was for your ivar delegate to be the thing that your property's accessors would get and set. Luckily, the compiler is clever enough to notice what you've done, and that's why it is emitting this warning:

警告:自动合成的属性'delegate'将使用合成的实例变量'_delegate',而不是现有的实例变量'delegate'[-Wobjc-autosynthesis-property-ivar-name-match]

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

这是在告诉您,属性delegate将使用自动合成的ivar _delegate,而不是您明确声明的delegate ivar.

It's telling you that your property delegate will use the automatically synthesized ivar _delegate rather than the ivar that you explicitly declared, delegate.

因此,如果仅删除delegate ivar,则编译器将停止发出此警告.如果您直接使用delegate ivar(而不是通过属性),请改用_delegate.

So if you simply delete your delegate ivar, the compiler will stop emitting this warning. If you were using the delegate ivar directly (not through the property), start using _delegate instead.

此选项的一个小变化是显式声明与delegate属性的自动综合正在创建的相同的ivar(_delegate).您可以通过替换

A minor variation on this option is to explicitly declare the same ivar (_delegate) that the automatic synthesis of the delegate property is creating. You can do this by replacing

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

使用

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

之所以有用,是因为自动合成属性将始终使用一个ivar,该ivar的名称是带有下划线的属性名称.如果不存在这样的ivar,则将生成该ivar.如果确实存在,将使用它.

This works because automatic synthesis of a property will always use an ivar whose name is the property's name prefixed with an underscore. If no such ivar exists, the ivar will be generated. If it does exist, it will be used.

如果相反,您希望设置属性的访问器并获取ivar delegate,则可以在类的@implementation中添加@synthesize指令,以告诉编译器执行以下操作:

If instead you would prefer that your property's accessors set and get your ivar delegate you can add an @synthesize directive to your class' @implementation to tell the compiler to do just this:

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

@synthesize delegate = delegate;行告诉编译器在属性delegate(分配的左侧)的访问器中使用ivar delegate(分配的右侧).

The line @synthesize delegate = delegate; tells the compiler to use the ivar delegate (the right hand of the assignment) in the accessors for the property delegate (the left hand side of the assignment).

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

You can also omit the right hand side of the @synthesize assignment and just write

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

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

This works because a property with a manual @synthesize which does not explicitly specify the ivar to be gotten and set by its accessors (such as @synthesize delegate;) will use an ivar with the same name as the property, NOT prefixed by an underscore. This has to do with backwards compatibility.

这篇关于自动合成的属性"delegate"将使用合成的实例变量"_delegate",而不是现有的实例变量"delegate"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆