Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

objective c - Autosynthesized property 'delegate' will use synthesized instance variable '_delegate', not existing instance variable 'delegate'

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: Autosynthesized property 'delegate' will use synthesized instance variable '_delegate', not existing instance variable 'delegate'

Can anyone advise how to get rid of the warning

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

Why does this work?

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

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.

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).

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.

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:

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

It's telling you that your property delegate will use the automatically synthesized ivar _delegate rather than the ivar that you explicitly declared, 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.


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

with

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

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.


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

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).

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

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

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...