what is the difference between local declarations in objective-c [duplicate] - ios

This question already has answers here:
Is there a difference between an "instance variable" and a "property" in Objective-c?
(6 answers)
Closed 9 years ago.
What is the difference between these declarations, lets call them red and orange:
pros, cons?

The red set is properties, and the orange set is instance variables.
A property declaration tells the compiler to define a getter method, and possibly a setter method. (No setter method if the property is readonly.)
In newer versions of Objective C, declaring a property also creates an instance variable that is used to save values for the property. By convention the instance variable has the same name as the property, but with an "_" prefix. There is a way to change the name of the instance variable, but let's ignore that for now.
The property foo:
#property (nonatomic, strong) NSString *foo;
Would have a getter method:
- (NSString *) foo;
and a setter method
- (void) setFoo: (NSString *) foo;
That enables you to use code like this:
NSString *aString = self.foo;
or
NSString *aString = [self foo];
(2 different, equally valid ways of invoking the getter)
And invoking the setter
self.foo = #"a string";
or
[self setFoo: #"a string"];
(2 different, equally valid ways of invoking the setter)
Properties are really useful when you want to create a public interface to get and set values in your class from outside. If you declare a property as "atomic" the compiler adds additional code to the getter and the setter so reads and writes to the property are "thread safe", and can be accessed from background threads.
Before ARC, properties also were a very clean way to manage retains and releases. You declared a property as "retain" and the setter was written to retain the object that was passed in. That's less of an issue in ARC, because the system takes care of retains and releases for you.
It is also possible to write a custom getter or setter method that invokes your own code instead of the compiler-written code. You can use that to do things like log information, send notifications about changes, update labels, etc, etc. You simply add a method body to your .m file that has the same method signature as the getter or setter and the compiler uses that method instead of the automatically generated one.
As I said before, the code:
self.foo = #"a string";
is the same as
[self setFoo: #"a string"];
and invokes the setter method. The setter method sets the internal instance variable _foo.
However, the code
_foo = #"a string";
changes the instance variable directly, without invoking the setter. If you do define a property, you should use it instead of the instance variable.

Objective-c use to be simple...and tedious. You would declare instance variables for a class (the orange) and then you would define (usually) 2 methods for each, one so that an external class could set each instance variable to a new value, and one that returned the ivars value so an external object could read it. Aka, you had to write a getter and setter for each ivar. This was two lines of code in the interface and sometimes around 10 lines of code for the implementation file.
Then came properties, declared with #property. There was much rejoicing and drinking in the streets. These single #property lines told the compiler to write those methods for you, including the correct memory management code and even mutex locking code (depending on what you specified when declaring the #property)
Theres a whole lot of history, but nowadays, with automatic reference counting, it really only makes sense to use #properties in your interface, when you want to make an ivar public, and declare your private ivars in your implementation file.
Lastly, not that #property not only tells the compiler to implement your getter and setter, but it also automatically provides an instance variable with the same name, but prefixed with an underscore (this is only if you have implicit synthesizing of properies enabled...more history)
So, thats the difference. #property tells the compiler to write code for you (essentially). What code it actually writes is modified by all the different ways you can declare a #property.

Related

Using the word 'set' on a class's property in Objective-C

I'm learning iOS development and choose to move back and forth between Objective-C and Swift to notice differences or similarities. While working through a tutorial in Objective-C, I noticed that Xcode autocomplete feature allows my code from the tutorial which reads:
taskField = [[UITextField alloc] initWithFrame:fieldFrame];
[taskField setBorderStyle:UITextBorderStyleRoundedRect];
[taskField setPlaceholder:#"Type a task, tap Insert"];
I decided to lookup UITextField reference pages, change the reference page's language to Objective-C, and noticed that the properties don't generally use the pre-text 'set'. Should the pre-text 'set' be used at all times for properties when writing in Objective-C?
Thank you in advance.
Short answer is that the following two lines are equivalent in this case:
taskField.borderStyle = UITextBorderStyleRoundedRect;
[taskField setBorderStyle:UITextBorderStyleRoundedRect];
set is the standard prefix on a "setter" method-- this can be a little confusing if you're new to ObjC. The actual property name here is e.g. borderStyle, and if you use the dot syntax setter, you would write taskField.borderStyle = .... If you invoke the setter with the message notation (brackets), then you use the setBorderStyle: explicitly.
Here's the history that explains this: Way back (10+ years ago anyway), ObjC did not have any declared, formal properties, and did not have "dot" syntax for accessing them. You'd create a "private" instance variable, and then you would write the idiomatic getters and setters for that value. By convention, the setter was prefixed with "set" and the getter had no prefix (it was just the "property name"). All access to that value, both get and set, was done with bracket notation. Fast forward through some intermediate evolution, and now the handy #property declaration will do a lot of automatic synthesis for you of all the once-cumbersome boilerplate code you used to have to write. The method synthesis naming rules are automatic and follow the earlier conventions. Most documentation today will demonstrate property access using dot notation, but the getter and setter methods are autogenerated, and are still available for direct use.
So in short, most often by convention, you will now write taskField.borderStyle = ..., but you can also call [taskField setBorderStyle:...]. The former essentially invokes the latter method, and both are semantically the same.
You access or set an object’s properties via accessor methods:
NSString *firstName = [somePerson firstName];
[somePerson setFirstName:#"Johnny"];
By default, these 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 synthesized methods follow specific naming conventions:
The method used to access the value (the getter method) has the same name as the property.
The getter method for a property called firstName will also be called firstName.
The method used to set the value (the setter method) starts with the word “set” and then uses the capitalized property name.
The setter method for a property called firstName will be called setFirstName:.
If you don’t want to allow a property to be changed via a setter method, you can add an attribute to a property declaration to specify that it should be readonly:
#property (readonly) NSString *fullName;
For details see this link Use Accessor Methods to Get or Set Property Values

Confused about properties and ivars

I realize that there are already many property vs. ivar questions on here, but after doing a lot of research I can't seem to find a clear answer.
I understand that when you declare a property like the following, that the compiler automatically synthesizes the backing ivar and the two accessor methods for you:
#property NSString *myString;
What still confuses me is, is myString an actual instance variable? The reason I ask this is because you can never access it like this:
NSLog(#"Value of myString is: %#", myString);
You either have to use the backing ivar _myString, or one of the getter methods like [self myString] or self.myString. So I'm confused because normally you could just use the variable name plain and simple.
To top it all off, I've been told that you should not refer to myString as a property, and that the word property should only be used to refer to the two accessor methods that are synthesized for you by the compiler when you use the #property directive.
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it?
Any help clearing this up would be greatly appreciated. I've been struggling with solidifying the idea of properties and ivars being different things all day now.
Here are answer of your questions -
is myString an actual instance variable? - No
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it? - No its not wrong to call it.
So it looks like what actually confuses you is naming conventions, if you go through the naming conventions behind properties -
When you use the #property syntax to declare properties on an object, as described in “Encapsulating Data,” the compiler automatically synthesizes the relevant getter and setter methods (unless you indicate otherwise). If you need to provide your own accessor method implementations for any reason, it’s important to make sure that you use the right method names for a property in order for your methods to be called through dot syntax, for example.
Unless specified otherwise, a getter method should use the same name as the property. For a property called firstName, the accessor method should also be called firstName. The exception to this rule is for Boolean properties, for which the getter method should start with is. For a property called paused, for example, the getter method should be called isPaused.
The setter method for a property should use the form setPropertyName:. For a property called firstName, the setter method should be called setFirstName:; for a Boolean property called paused, the setter method should be called setPaused:.
Check the developer website for detailed description -
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
I'm pretty much a noob in objective c, but i understand it as follows:
As any other OOP language objective c has instance vars and getters+setters methods.
Basically every getter or setter looks the same, so XCode let you synthesize those automatically using the #property syntax.
In previous versions on XCode you had to declare both the ivar and its #property + #synthesize, but now the compiler does that for you.
This code:
#interface SomeClass : NSObject {
NSString* _myInstanceVar; //declare the ivar
}
#property (non-atomic, strong) myInstanceVar //declare the property+accessors
Is equivalent to this code:
#property (non-atomic, strong) myInstanceVar //declare the ivar+property+accessors
This documentation pretty much sums its up.
Hope i helped in anyway...

IOS: property and self [duplicate]

This question already has answers here:
iOS: Usage of self and underscore(_) with variable [duplicate]
(3 answers)
Closed 8 years ago.
When I declare an NSString I simply do:
NSString * my_string; (in interface of my .h)
If I want to allow access to this string from other classes I add a property in this way
property (nonatomic, strong) NSString *my_string;
and I write the synthesize
synthesize my_string; (in .m)
Now I have some question about:
If I use a property, must I also use the simple declaration in interface?
If I use my_string as a property, must I always use self. before?
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
If I use a property, must I also use the simple declaration in interface?
No, generally you just want to use the #property (it will quietly add an instance variable for you).
If I use my_string as a property, must I always use self. before?
You don't need to but you should. Using self. calls the accessor method to get the variable contents. Not using self. accesses the instance variable directly. So, if you add a custom accessor in the future you will need to refactor.
Often you will reuse the same variable multiple times. In this case, call self., but use it to set a local variable that you then use throughout the method (in this way the accessor is only called once).
If I use a property, is it necessary to write #synthesize for each? (because I saw that sometimes it's not necessary.
No, the compiler will add:
#synthesize propertyName = _propertyName;
for you, and that is a good approach to follow (separating the property name from the instance variable name).
NO
NO, using self. will execute accessor method, you can use it with name _my_string and then you'll access the variable directly. If you want a different variable name for your property then you must use synthetize with that name
NO, xcode will synthetize it automatically with the variable named _my_string
It's becoming more and more appropriate to use properties in all cases anymore. You can declare "private" properties inside a header extension inside the .m file if you don't want to expose them to outside classes. Say you have a property called name in the .h file:
#property (nonatomic, strong) NSString *name;
Users of this class can access the name property by saying theVariable.name, inside your .m file you need to access this property with self.name. However you can access the ivar like so:
_name = #"John Smith"
This will skip the property and go directly to the ivar. In this case if you had an overriden setter it won't be called.
You no longer need to synthesize properties. Xcode will automatically provide this:
#synthesize name = _name;

Need assistance regarding Objective-c properties concept

I am reading Apple Doc for understanding property instance variable but bit confused
From Apple Doc:
Most Properties Are Backed by Instance Variables By default, a
readwrite property will be backed by an instance variable, which will
again be synthesized automatically by the compiler.
An instance variable is a variable that exists and holds its value for
the life of the object. The memory used for instance variables is
allocated when the object is first created (through alloc), and freed
when the object is deallocated.
Unless you specify otherwise, the synthesized instance variable has
the same name as the property, but with an underscore prefix. For a
property called firstName, for example, the synthesized instance
variable will be called _firstName.
Although it’s best practice for an object to access its own properties
using accessor methods or dot syntax, it’s possible to access the
instance variable directly from any of the instance methods in a class
implementation. The underscore prefix makes it clear that you’re
accessing an instance variable rather than, for example, a local
variable:
If using accessor methods or dot syntax is best practice then why user _ivarPropertyName?
Why use ivar for presenting properties? what are its benefits? when apple says "using accessor methods or dot syntax is best practice"
#property declares the existence of a property (describing its interface), but doesn't specify the implementation of that property. But properties need to store their contents somewhere. By default, the compiler synthesizes an ivar for that (and matching setters and getters). So normally you can ignore the existence of the ivar and just use dot syntax.
I follow Apple's advice and try to avoid using ivars directly. But somtimes you want to access a property without invoking its getter. The most common exception in my code is lazily-initialized read-only properties:
#interface MyObject : NSObject
#property ( nonatomic, readonly ) id someProperty ;
#end
#implementation MyObject
#synthesize someProperty = _someProperty ; // required; compiler will not auto-synthesize ivars for readonly properties
-(id)someProperty
{
if ( !_someProperty )
{
_someProperty = ... create property here
}
return _someProperty ;
}
#end
Also, you may not want to invoke the getter for a property in your -dealloc method... for example, a timer property. To avoid creating a timer in -dealloc, access the ivar directly:
-(void)dealloc
{
[ _myTimer invalidate ] ; // don't use self.myTimer here, that would create a timer even though we're going away...
}
There are probably more use cases. For most properties you don't even need to use the ivar, just use <value> = self.property and self.property = <new value>.
edit:
Also, there will be some additional overhead for accessing the property via message dispatch (using dot-accessor syntax or the getter) vs directly accessing the ivar, but it will make no difference in almost all cases.

Why must I define variables twice in the Header file?

Why must I define variables twice in the header file? What differences are there between these variables?
The first definition is here:
#interface MyController: UIViewController
{
NSInteger selectedIndex;
}
The second definition is here:
#property (nonatomic) NSInteger selectedIndex;
What you're seeing was required in earlier versions of Objective-C,
but isn't any more.
In the first versions of Objective-C used by NeXT up until the new
runtime was introduced (with Objective-C 2.0 on Mac OS X), all
instance variables had to be declared as part of the class's structure
in its #interface. The reason was that if you subclassed a class,
the compiler needed to know the instance variable layout of the class
so it could see at what offset to put the subclass's instance
variables.
When properties were introduced, synthesized properties had to be
"backed" by an instance variable in the class's structure. Therefore
you had to declare both an instance variable and the property.
All of the above is no longer true. Newer Objective-C is less fragile
in the way it looks up instance variable offsets, which has meant a
few changes:
not all instance variables need to be in the #interface. They can now be defined in the #implementation: though not in categories due
to the possibilities of clashing and other issues.
instance variables for synthesized properties can be inferred and created based on the property definition.
you can programmatically add instance variables to classes you're creating at runtime (only before you've registered the class as
available to the system).
So, to reiterate, you only needed to declare both the instance
variable and a synthesized property in older versions of the
Objective-C language. What you're seeing is redundant and should not
be considered a "best practice".
[Source]
As others have pointed out, it is no longer necessary to declare a backing instance variable for a synthesized property in the header.
To make this a bit clearer though: What you're seeing are not two declarations of the same variable, it is one declaration of the variable and one declaration of the property.
A property is basically a set of methods (in this case selectedIndex and setSelectedIndex:) that are typically used to access instance variables. There is a difference between a property and an instance variable. The property's setter/getter could do more than just set the variable, in your example, it could also e.g. update the UI to reflect the change of the selected index or the getter could infer the index from some other variable (in this case, there might be a selection index path), etc.
Synthesizing a property simply frees you of implementing those methods yourself and provides you with default implementations that simply set the variable, but you could also implement selectedIndex and setSelectedIndex: yourself just like any other method in which case you might either need the instance variable itself or omit it altogether (in case of an inferred property).
In modern runtime you do NOT need to declare them twice. Just use:
In you .h
#property (nonatomic) NSInteger selectedIndex;
The part between the {} is the declaration of the iVar. And with your #property you declare getter and setters. In modern runtime if you just use the code above you say basicly the same (your iVar is now _selectedIndex).

Resources