Using 'variable' vs '_variable'? [duplicate] - objective-c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
I'm currently learning Objective-C and I'm following a tutorial that uses variables a little funny (to me at least!).
Basically, class variables are declared like this:
#interface .. {
UITextField *_titleField;
UIImageView *_imageView;
}
#property (retain) IBOutlet UITextField *titleField;
#property (retain) IBOutlet UIImageView *imageView;
and then synthesized like this:
#synthesize titleField = _titleField;
#synthesize imageView = _imageView;
So basically, whats the purpose of this?

titleField is the synthesized property and _titleField is the backing field for it.
Maybe http://mutelight.org/articles/the-objective-c-retain-property-pattern will help you understand it better

Often people use the _ character as a marker for an instance variable (a.k.a. in other languages a ‘field’, or ‘member’, etc). Some people put an underscore after the variable name, some people put it before, some people don't use it at all, some people use different prefixes. The idea is that it helps you distinguish at a glance what are instance variables and what aren't.
Of course, if you do decide to name your instance variables in a particular way, but still want your properties to have ‘normal-looking’ names, you need to map the ‘normal-looking’ name to the ‘instance variable’ name.

A property is just a marker for a pair of methods - 'foo' and 'setFoo' (unless the property is readonly, in which case only 'foo' will by synthesized). A variable (those are instance, not class variables, BTW) is the actual memory store. Properties can be associated with a memory store - this is what #synthesize does - but don't have to. The point being, properties and instance variables often go together but are distinct.

Related

What are the circumstances that cause a #property to not automatically create an instance variable? [duplicate]

This question already has answers here:
Under what conditions is #synthesize automatic in Objective-c?
(5 answers)
Closed 7 years ago.
I've only been in the Objective-C & Cocoa world for a year, so I wasn't around when properties weren't automatically synthesized
Whenever I create new classes in our project, I can declare #property BOOL testFlag without declaring an instance variable. Then, in the implementation, I could either call self.testFlag, [self testFlag], [self setTestFlag:NO]. But, I could also call _testFlag. I always assumed because properties are automatically synthesized with instance variables, that's why I can just append a "_" underscore before the property name to directly access the instance variable.
However, I have been refactoring really old files, that clearly were created before auto-synthesizing was a thing
So now in the header, I'd see something like this:
#interface testClass
{
BOOL _testFlag
}
#property BOOL testFlag;
In the implementation, there could be a custom setter/getter:
#implementation testClass
#synthesize testFlag = _testFlag;
-(void)setTestFlag:(BOOL)testFlag
{
_testFlag = testFlag;
}
-(BOOL)testFlag
{
return _testFlag;
}
But I thought because of auto-synthesizing, I could remove the _testFlag declaration in the header, and I could remove the #synthesize in the implementation. But when I do this, there are just a truck ton of errors; wherever somebody was directly trying to access the ivar _testFlag. (This actually includes the custom getter/setter above ^^, too)
Is there perhaps something I am missing with the project settings that prevent this old file from generating an implied instance variable for properties?
Remove the getter and setter to have automatic synthesis of the backing variable. When you supply both for the property, the assumption is that you're going to look after storage yourself.

Declare instance variable nonproperty and property same name [duplicate]

This question already has answers here:
Do declared properties require a corresponding instance variable?
(6 answers)
Closed 9 years ago.
Why in many fragment code declare instance variable like and for what? what different about property and non property
#import <Foundation/Foundation.h>
#interface class1:NSObject
{
NSMutableString *currentData;
}
#property (nonatomic, retain) NSMutableString * currentData;
What you saw is an "old code"... but sometimes you still need to support old versions (e.g. 10.5).
A property is simply a couple of getter and setter (well.. it depends on the attributes you choose: e.g. readonly will generate only a getter).
But a property operates (and so it needs) an instance variable. Usually what you see in the implementation file is something like
#implementation class1
#synthesize currentData = currentData;
#end
This means create getter and setter which uses currentData as variable.
For newer version you don't need to create the instance variable and you can just type the property and synthesize statement. In the most recent language version you don't even need the synthesize statement. Automatically an instance variable named _propertyName (underscore + name of the property) is created.
BTW: sometimes you still need to make your own getter and/or setter. Classic naming convention applies (e.g. - (void)setCurrentData: (NSMutableString*)newData; for setter and - (NSMutableString*)currentData; for getter), but same rules as before for properties: if you support only the most recent OSes you can just write the #property statement and right your getter and setter by using the "underscored" variable...

About naming the instance variable in Objective C

Sometimes we may explicitly specify the name of an instance variable in the synthesize statement, e.g.,
In SomeViewController.h,
//....
#property (nonatomic, retain) NSObject *variable;
//....
In SomeViewController.m,
//....
#synthesize variable = _variable;
//....
But why bother making this extra effort if the instance variable will be implicitly named as _variable even if we simply put it as:
#synthesize variable;
in the SomeViewController.m.
Can anyone share some idea on why it is necessary? Thank you :D
Just to avoid confusion (see comments): Using the = _variable part of the #synthesize is not required, nor is the #synthesize itself required any more.
This effort is only requied, when you want to link the property to a specific instance variable. With earlier Objective-C versions this part of the statement was required to set the name to something different from the property name, so when you want to call the iVar _variable and the property variable. The default would be variable (unlike your question). Without that = something ivar and property have the same name.
BTW, there is nothing wrong with using the same name for both. But having different names, a leading _ would do, makes it more clear to the programmer whether he/she accesses the ivar directly or though the accessor methods. Sometimes this is of vast importance, especially when not using ARC. Therefore it helps avoiding errors.
With current Objective-C, however, you could omit the #synthesize statement at all and go with the defaults in that case. The default automatically synthesized instance variable name would have a leading _ so _variable in your example.

Property - Implementation of variables in Objective-C

Well ! I got confused about the way of declaring variables & implementing its properties.
The .h File contents
#interface XYZAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet XYZViewController *viewController;
#end
The .m File Contents
#import "XYZAppDelegate.h"
#import "XYZViewController.h"
#implementation XYZAppDelegate
#synthesize window=_window;
#synthesize viewController=_viewController;
My questions/Queries are as follows.
Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
What are the additional features other than this ? ( In coding specific )
Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
You do not have to declare the
variable. It is done automatically,
I believe by #synthesize. One
advantage to declaring it is that the
debugger will automatically list it.
Weigh this against the ugliness of
redundant definition.
Other features: read only properties,
assigned (unretained) values.
The underscore is a convention for
naming member variables that are
differently named than properties and
method variables. Apple's samples
sometimes use this convention and
sometimes do not. I view it as
usually unnecessarily verbose as a
programmer can easily tell the
difference between myVariable and
self.myVariable.
1) Don't we require to declare variables if we put property ? ( Using property, we can indirectly declare variable - is it like that ? )
No. You aren't required to declare variables for the corresponding properties. You are required to use the #synthesize propertyName command which tells the compiler to create those variables for you.
2) Why does everybody insist to use _ before each property accessor ? ( Other than security threats ? Has it become coding standard ? Whats the reason behind it? )
Most people (all?) have been stung by memory management nightmares. Some of these are caused by sloppy/lazy/zero-sleep coding. Using #synthesize propertyName = _propertyName allows the programmer to immediately know that the underscored variable is private to the class, and is unretained. It prevents issues where you specifically allocate or copy an object to store in the property, or accidentally assign an autoreleased object to the ivar.
Consider:
1) An autoreleased object being assigned to an unretained ivar.
#synthesize propertyName;
propertyName = [NSString stringWithFormat:#"I've just made %#", "a boo-boo."];
"propertyName" now references an object that will soon not exist, which will create EXEC_BAD_ACCESS errors down the road (as soon as it's referenced again).
2) A retained object being set to the retained property.
#synthesize propertyName;
self.propertyName = [[NSString alloc] initWithFormat:#"I just created %#", #"a leak"]
Now we've created an NSString object, and set it to the propertyName property, which itself is retaining the variable. Now the object is double retained and won't be properly released.
Both of these issues are easy to combat (even when tired, albeit less so) when you properly name your ivars with an underscore. It's not a fool-proof method, but it makes it considerably easier to manage the retain counts of objects in your head.
(1) No, not with the new 64-bit only features. The variables are declared for you, automatically.
(2) I don't know what you're asking here.
(3) It's just a convention, so that the variable name is different from the accessor name. Makes it clearer which you're dealing with.

Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects

I'm currently using the iOS 5 SDK trying to develop my app.
I'm trying to make an NSString a property, and then to synthesize it in the .m file (I have done this before with no issues). Now, I came across this: "Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects."
This is my code:
.h
#interface ViewController : UIViewController {
NSString *newTitle;
}
#property (strong, nonatomic) NSString *newTitle;
.m
#synthesize newTitle;
Does anyone have a clue how I could fix this?
Thanks!!
My guess is that the compiler version you’re using follows the memory management rules for declared properties, too — more specifically, for declared properties’ accessors:
You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”.
A property named newTitle, when synthesised, yields a method called -newTitle, hence the warning/error. -newTitle is supposed to be a getter method for the newTitle property, however naming conventions state that a method whose name begins with new returns an object that’s owned by the caller, which is not the case of getter methods.
You can solve this by:
Renaming that property:
#property (strong, nonatomic) NSString *theNewTitle;
Keeping the property name and specifying a getter name that doesn’t begin with one of the special method name prefixes:
#property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
Keeping both the property name and the getter name, and telling the compiler that, even though the getter name starts with new, it belongs to the none method family as opposed to the new method family:
#ifndef __has_attribute
#define __has_attribute(x) 0 // Compatibility with non-clang compilers
#endif
#if __has_attribute(objc_method_family)
#define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
#else
#define BV_OBJC_METHOD_FAMILY_NONE
#endif
#interface ViewController : UIViewController
#property (strong, nonatomic) NSString *newTitle;
- (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
#end
Note that even though this solution allows you to keep newTitle as both the property name and the getter name, having a method called -newTitle that doesn’t return an object owned by the caller can be confusing for other people reading your code.
For the record, Apple have published Transitioning to ARC Release Notes, in which they state:
You cannot give a property a name that begins with new or copy.
They’ve already been notified that their statement is not quite accurate: the culprit is the getter method name, not the property name.
Edit 17 Jan 2015: I’ve just noticed a recent commit to Clang that suggests option 3 above (using objc_method_family(none)), including a fix-it, for the general case where a property name matches one of the special method family prefixes. Xcode will likely incorporate this change eventually.
Unacceptable Object Names
newButton
copyLabel
allocTitle
Acceptable Object Names
neueButton
mCopyLabel
_allocTitle
#arc #auto-synthesized #xcode-4.6.1
** EDIT **
Apparently you can't use mutableCopy either.
The name of the member starting with new is what triggers the warning. Change the name to editedTitle and the warning will go away. I was unable to find documentation confirming this but through testing was able to determine that member variables that begin with 'new' aggravate the compiler.
ARC does not allow to use "New...." in property name. but you can use "newTitle" by changing getter name.
#property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
It doesn't look like what Bavarious was suggesting was what you wanted to do. All you want to do is declare an instance variable NewTitle and then synthesize the property. We used to have to declare the instance variable and property. No more.
Now, I believe the right way of doing this is the following:
.h
#interface ViewController : UIViewController
#property (nonatomic, strong) NSString *newTitle;
.m
#synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
The instance variable for the property newTitle is synthesized. You don't want your instance variable to be the same as your property - too easy to make mistakes.
See Example: Declaring Properties and Synthesizing Accessors
In CoreData if you use "new..." in attribute (compile normally) it will crash randomly with a "bad access" exception.
There is no crash log and the line shown with the "All Exceptions Breakpoint" will not help you at all.
Writing a setter manually with the name same as the property's removed this warning.
NS_RETURNS_NOT_RETAINED is used to solve the naming problem.
#property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
We can find its definition as follows:
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
The 'ns_returns_not_retained' attribute is the complement of 'ns_returns_retained'. Where a function or method may appear to obey the Cocoa conventions and return a retained Cocoa object, this attribute can be used to indicate that the object reference returned should not be considered as an "owning" reference being returned to the caller. The Foundation framework defines a macro NS_RETURNS_NOT_RETAINED that is functionally equivalent to the one shown below.
Besides the issue that you should/can't use "new" in front of you property names, let say one more thing: Try to avoid "new" in front of names in general. "New" is dependent on time. Currently it is new for you, but some time later you maybe want to implement something new again. So using "new" in names is always bad. Try to think this way: In the programming world, "new" is always creating something: a new instance of something.
In your case when you want to assign a different title then the current name your property titleReplacement.
One more thing: Try to name functions and methods with the verb first, like setSomething or getSomething.
But in properties try to name the object first, like heightMinimum, heightMaximum, etc. -> when you use your inspector when you are coding, you always looking for objects. Try it out. ;-)
try this:-
#property (nonatomic,retain) NSString *newTitle;