18

我正在按照此处的指南创建自定义委托。它运行良好,但我在 xcode 中收到以下警告

DetailViewController.m:23:1:自动合成的属性“delegate”将使用合成的实例变量“_delegate”,而不是现有的实例变量“delegate”

谁能建议如何摆脱警告

4

2 回答 2

39

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

为什么这行得通?

Xcode 4.4 (LLVM Compiler 4.0)开始,如果@synthesize指令没有显式用于该属性,则实例变量和访问器方法会自动为该属性合成。正如Apple 关于封装的文档所述

默认情况下,编译器会自动为您合成 [...] 访问器方法,因此您无需执行任何操作,只需在类接口中使用 @property 声明属性。

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

在这种情况下,属性名称是delegate,所以使用的 ivar 是_delegate。这已经在您的代码中发生了。当您调用-delegateand时,将获取并设置 -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,.

因此,如果您只是删除您的delegateivar,编译器将停止发出此警告。如果您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,而不是以下划线前缀。这与向后兼容性有关。

于 2013-01-06T17:28:53.323 回答
2

还有另一种方法,这个方法对我有用:

@property (nonatomic, unsafe_unretained) id <MyDelegate> delegate;

然后,您可以将其添加到实现中而不会出错:

@synthesize delegate;

另外:这是符合 ARC 的。

于 2013-02-21T14:51:10.827 回答