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

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

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.

There's another method and this one worked for me:
#property (nonatomic, unsafe_unretained) id <MyDelegate> delegate;
You can then add this to the implementation without error:
#synthesize delegate;
Also: This is ARC compliant.

Related

Subclass does not have ivar of parents' public property

I'm learning objective-c and there is something I couldn't find an answer to.
I have declared a property in the public interface of a class.
In that class I can access the ivar directly by using underscore, without synthesizing the property.
For example:
// Class.h
#property (nonatomic, strong) NSString *someString;
// Class.m
_someString = something;
But if I subclass that class, I can access the setter and getter without any extra code, but I can't access the ivar directly, unless I explicitly synthesize the property, which was not necessary step in the superclass.
I know for a fact that it does create ivars specific for the subclass, because I have 2 subclasses of the same superclass, and each have their own values for the superclass's properties.
I just don't understand why I need to explicitly synthesize the subclass if I want to access the ivars directly.
It isn't really a problem, but more of a curiosity.

When should I use #synthesize explicitly?

As far as I know, since XCode 4.4 the #synthesize will auto-generate the property accessors. But just now I have read a sample of code about NSUndoManager, and in the code it noticed that the #synthesize is added explicitly. Like:
#interface RootViewController ()
#property (nonatomic, strong) NSDateFormatter *dateFormatter;
#property (nonatomic, strong) NSUndoManager *undoManager;
#end
#implementation RootViewController
//Must explicitly synthesize this
#synthesize undoManager;
I am feeling puzzled now... When should I add #synthesize explicitly to my code?
There's a lot of answers, but also a big confusion. I'll try to put some order (or increase the mess, we'll see...)
Let's stop talking about Xcode. Xcode is an IDE. clang is a compiler. This feature we are discussing is called autosynthesis of properties and it's an Objective-C language extension supported by clang, which is the default compiler used by Xcode.
Just to make it clear, if you switch to gcc in Xcode, you won't benefit from this feature (regardless from the Xcode version.) In the same way if you use a text editor and compile using clang from the command line, you will.
Thank to autosynthesis you don't need to explicitly synthesize the property as it will be automatically synthesized by the compiler as
#synthesize propertyName = _propertyName
However, a few exceptions exist:
readwrite property with custom getter and setter
when providing both a getter and setter custom implementation, the property won't be automatically synthesized
readonly property with custom getter
when providing a custom getter implementation for a readonly property, this won't be automatically synthesized
#dynamic
when using #dynamic propertyName, the property won't be automatically synthesized (pretty obvious, since #dynamic and #synthesize are mutually exclusive)
properties declared in a #protocol
when conforming to a protocol, any property the protocol defines won't be automatically synthesized
properties declared in a category
this is a case in which the #synthesize directive is not automatically inserted by the compiler, but this properties cannot be manually synthesized either. While categories can declare properties, they cannot be synthesized at all, since categories cannot create ivars. For the sake of completeness, I'll add that's it's still possible to fake the property synthesis using the Objective-C runtime.
overridden properties (new since clang-600.0.51, shipping with Xcode 6, thanks Marc Schlüpmann)
when you override a property of a superclass, you must explicitly synthesize it
It's worth noting that synthesizing a property automatically synthesize the backing ivar, so if the property synthesis is missing, the ivar will be missing too, unless explicitly declared.
Except for the last three cases, the general philosophy is that whenever you manually specify all the information about a property (by implementing all the accessor methods or using #dynamic) the compiler will assume you want full control over the property and it will disable the autosynthesis on it.
Apart from the cases that are listed above, the only other use of an explicit #synthesize would be to specify a different ivar name. However conventions are important, so my advice is to always use the default naming.
If you do not explicitly use #synthesize the compiler will understand your property the same way if you had written
#synthesize undoManager=_undoManager;
then you will be able to write in your code things like :
[_undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
This is the common convention.
if you write
#synthesize undoManager;
you will have :
[undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter
Personally I stop using #synthesize, since it's not mandatory any more.
For me the only reason to use #synthesize is to link an iVar to a #property. If you want to generate specific getter and setter for it.
But in the given piece of code there is no iVar, I think that this #synthesize is useless. But now I think the new question is "When to use iVar ?", and I've no other response than "never" for this one !
When should I add #synthesize explicitly to my code?
Generally, if it's required: You will probably never hit a case where it's needed.
There's one case you might find it useful, though.
Say you're writing both a custom getter and setter, but want an instance variable to back it. (For an atomic property, this is as simple as wanting a custom setter: the compiler will write a getter if you specify a setter for a monatomic property, but not an atomic property.)
Consider this:
#interface MyObject:NSObject
#property (copy) NSString *title;
#end
#implementation MyObject
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
This will not work, because _title doesn't exist. You've specified both a getter or setter, so Xcode (correctly) doesn't create a backing instance variable for it.
You have two choices for making it exist. You can either change the #implementation to this:
#implementation MyObject {
NSString *_title;
}
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
Or change it to this:
#implementation MyObject
#synthesize title = _title;
- (NSString *)title {
return _title;
}
- (void)setTitle:(NSString *)title {
_title = [title copy];
}
#end
In other words, although synthesize is for practical purposes never necessary*, it can be used to define property-backing instance variables when you're providing a getter/setter. You can decide which form here you want to use.
In the past, I've favoured specifying the instance variable in the #implementation {}, but I now think the #synthesize route is a better choice as it removes the redundant type and explicitly ties the backing variable to the property:
Change the property's type, and the instance variable's type changes.
Change its storage qualifier (for instance, make it weak instead of strong or strong instead of weak) and the storage qualifier changes.
Remove or rename the property, and the #synthesize will generate a compiler error. You won't end up with stray instance variables.
*-I know one case where it was necessary, relating to splitting functionality across categories in multiple files. And I wouldn't be surprised if Apple fixes this, or even already has.
OK, when you create a property...
#property NSString *name;
Xcode will auto synthesise an iVar as if you had written...
#synthesize name = _name;
This means you can access the property with...
self.name;
// or
_name;
Either will work but only self.name actually uses the accessor methods.
There is only one time that auto synthesise does not work: If you overwrite but the setter AND the getter method then you will need to synthesise the iVar.
You are fine if you just override the setter or if you just override the getter. But if you do both then the compiler won't understand it and you will need to synthesise it manually.
As a rule of thumb though.
Don't make iVars.
Just use the property.
Don't synthesise it.
Property synthesis is required when a property is declared in a protocol. It will not be automatically synthesized in an implementing interface.
Thanks for clarifying that. I had a similar problem.
#synthesize firstAsset, secondAsset, audioAsset;
#synthesize activityView;
So now, having commented them out, I went through and replaced each occurrence with, for example
self.firstAsset It seems I could also use firstAsset, but I find I miss seeing the "" too often.
Xcode doesn't require an explicit #synthesize declaration.
If you don't write #synthesize its the same as doing :
#synthesize manager = _manager;
The sample code might've been old. They'll update it soon.
You can access your properties like :
[self.manager function];
This is Apple's recommended convention. I follow it, and I recommend that you do too!

Property vs. ivar in times of ARC

It is my understanding that setting an ivar now retains the object being assigned to it, since setting variables defaults to the strong qualifier. Because ivars are in the scope of the object they are declared in and strong retains objects within the scope of the variable, this means the ivars value would never be released while the object containing the ivar is still alive.
Is this correct?
If so, am I right in thinking that there is, in terms of memory management, no difference between a retaining (strong) property and a simple ivar anymore?
If a variable:
Is declared in a class using ARC.
Is used solely for class implementation (not exposed as part of the class interface).
Does not require any KVO.
Does not require any custom getter/setter.
Then it is appropriate to declare it as an ivar without a corresponding #property/#synthesize, and to refer to it directly within the implementation. It is inline with Encapsulation to declare this ivar in the class implementation file.
// MyClass.h
#interface MyClass : ParentClass
#end
// MyClass.m
#implementation MyClass {
NSString *myString;
}
- (void)myMethod {
myString = #"I'm setting my ivar directly";
}
#end
This ivar will be treated as __strong by the ARC compiler.
It will be initialized to nil if it is an object, or 0 if it is a primitive.
You can't use KVO and do custom getter and setters with instance variables other than that they are very similar when using ARC.

Differentiate between iVar and Method Parameter?

I have a property like this:
#property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder;
I want to adjust the setter, and XCode fills out the method signature like this:
-(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder {
However, to actually do anything in the method, I must change the parameter backgroundImageHolder to something like backgroundImageHolderIn. Is there any way to avoid this? Is there any way to set the iVar without reinvoking the setter (causing an endless loop), or just referring to the parameter again?
I just tried:
self->backgroundImageHolder = backgroundImageHolder;
but the compiler warns me anyway.
Note: I am using the automagically generated iVar that the compiler makes for the property, but by default its name is the same.
You can give tell the compiler how to name the generated ivar:
#synthesize propertyName = iVarName;
If there actually exists an ivar named iVarName that one is used. If it doesn't exist the compiler creates it for you.
Like:
#synthesize backgroundImageHolder = myBackgroundImageHolder;
Now you can access the instance variable myBackgroundImageHolder. You don't need to declare it in the interface first.
Well, the conflicting parameter name seems to be pretty well covered by now. Basically, you have to either:
Rename the incoming argument
Rename the synthesized iVar
Once you have a method argument that differs from the iVar you're attempting to set, you have everything you need to write a custom setter. To avoid the infinite loop, you have to not call the setter you're currently implementing, whether it be via dot syntax or method brace syntax. Instead, refer directly to the backing iVar. You'll need to take care to manually implement the memory management semantics you declared in the property though (assign vs. retain, etc.):
// Backed by _myProperty iVar.
- (void)setMyProperty:(NSInteger)myProperty {
// Insert custom code here...
[self setMyProperty:myProperty]; // Obviously bad.
self.myProperty = myProperty; // Less obviously bad (thanks dot syntax)
// but semantically identical to the previous line.
_myProperty = myProperty // Good, (assuming assign semantics).
}
Compiler warns you because when you declare #property it creates instance variable with exact same name as a property (and as a parameter of a setter method). One way to avoid it is to create differently named instance variable and then pair it with property using #synthesize like this:
// .h
#interface Foo : NSObject {
IBOutlet UIImageView *myfooImageView;
}
#property (nonatomic, retain) UIImageView *publicFooImageView;
// .m
#implementation Foo
#synthesize publicFooImageView=myfooImageView;
#end
The clearest thing to do would be this:
In your header, define an iVar for backgroundImageHolder like so
#interface Something : NSObject
{
IBOutlet UIImageView *_backgroundImageHolder
}
Notice the leading underscore.
Then in your .m file, use either the synthesize call like so:
#synthesize backgroundImageHolder=_backgroundImageHolder;
or just define the getter and setter methods yourself: Then you are able to access the ivar via "_backgroundImageHolder" without any danger of accidentally calling the setter again.

Why alias a new name and explicitly release the IBOutlet property?

Recently some example from Apple looks something like this:
#interface ViewController : UIViewController
{
**// Notice no more ivar here.**
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
#implementation ViewController
#synthesize webView = _webView;
...
- (void)dealloc
{
[_webView release];
[super dealloc];
}
My question is why aliasing the webView to _webView, and release in the dealloc since there is no ivar named _webView?
One more question, if I declare a property that has no related ivar, do I need to release it in dealloc?
When you #synthesize a property that doesn't have an associated ivar (whether you say #synthesize property or #synthesize property=_property), an ivar is generated for you. The default is to use the same name for the ivar as the property itself. If the property is a retain property, then you have to release the object in -dealloc or you'll have a memory leak.
Apple's convention is to name ivars (whether declared explicitly in the interface or implicitly in an #synthesize) with an underbar to indicate the private nature of the ivar. IMO it's also helpful to ensure that people use the ivar only when they intend to (since for some coders it seems to be easy to accidentally type myproperty when you mean self.myproperty, which can create significant bugs).
The answer to your last question is basically yes, though technically the answer is 'sometimes'. You only have to release the object if there is an object stored in an ivar that was retained. That's most of the time. However, properties are just a shortcut for invoking methods named 'myproperty' and 'setMyproperty' (etc), so it's possible to have a pair of methods with those names and an associated property that doesn't actually have an ivar paired with it. But if you're declaring properties with the retain attribute and synthesizing them, you should always release the objects their ivars point to.
I think Use of properties by Xcode 4 templates will explain this better and more in detail than I could.