NOTE: I am only talking about .m file here.
I am confused by these two things, both are said to be the way to declare internal instance variable:
Way 1:
#interface MyClass ()
// Declare instance variable which is only visible in this class
#end
#implementation MyClass
...
#end
Way 2:
#implementation MyClass {
// Declare instance variable which is only visible in this class
}
...
#end
What are the differences between these two ways of declaring instance variables?
In terms of functionality, there is no difference.
Declaring the ivars in a class extension -- the #interface MyClass() {...ivars...}#end pattern -- does allow you to move the ivar declaration to a header file that could then be used by other classes for direct access for internal-only use, for example.
After the "#interface" line, you can add instance variables within curly braces. That's instance variables, not properties. After the curly braces, or immediately after the "#interface" line if you have no curly braces, you add methods and properties.
So your first comment is wrong. Instance variables can only be added within the curly braces. Properties generate instance variables (usually but not always), but they are not instance variables.
Besides ivar, properties also generate setter and getter method if necessary (according your property attribute). But if you implement the setter and getter synchronously, compiler would not synthesize ivar, since the compiler will assume that you are taking control over the property implementation and won’t synthesize an instance variable automatically.
In Objective C the { } it’s the area where you declare instance variables. You can also use access member declaration in that section like #private #public & #protected. When you declares the "ivars" outside the {} the variable will be a file-scope variable (kind of static) and it won't be an instance variable of your class.
If you use properties (#property) the compiler is smart enough and will create its own ivars with its corresponding setter and getter.
Using a class extension in the implementation file allows you to add ivars or properties (and methods) that are only accessible by the implementation of the class extension. It also allows you to overwrite access of base classes like properties or private methods.
Related
I have noticed in many of the header documentation files in the Apple framework that define variables within brackets directly following the interface definitions like the variables a and b below:
#interface MyView : UIView {
#package
int a;
UIView b;
}
Normally I have just been declaring all variables as properties for the convenience of the synthesized methods. Can anyone tell me when it would be more efficient or more proper to declare variables under #package instead of as #properties?
#package is an access specifier, similar to how it works in Java (it allows access from any code at the same package level). But since the . syntax with Objective C objects works with properties, and not direct member access, you have to use the -> syntax instead, as if the object were a C struct, to access that variable directly.
An auto-synthesized #property instead creates a protected instance variable (prefixed with an underscore), which is read and set by the synthesized methods. Now, the overhead of using a property is negligible, compared with direct member access, so there's no real reason to stop using properties.
In your example, if you had a MyView* myview, you could set the view b directly, with myview->b = someotherview;. But this would give the class no chance to respond to the update (you would probably write the setter method so you can do something with it), nor does it ensure that the view provided is retained properly. These are the issues that properties were designed to avoid.
I am new in objective-c and iOS development. I have a simple question to ask:
I saw in some iOS class implementation file, people use the code like below:
#implementation BIDMyController
- (void)viewDidLoad{...}
The code above is quite straight forward. But, sometimes, I saw code of class implementation like below:
#implementation BIDMyController{
NSMutableArray *names;
}
- (void)viewDidLoad{...}
The only difference is that there are curly brackets added, which includes some variable definition. What does the curly brackets & the variables mean? Are they the Object-C style of defining private variables of this class ?? Could someone explain to me?
Yes, it's a way of declaring instance variables (ivars) that are only visible internally.
See: https://stackoverflow.com/a/6891326/1597531
First let's explain what are iVars, and then why they're declared on the implementation file:
Those are called instance variables (iVars) they are not specifically private variables.
You can change the way iVars behave with the following directives:
#private
The iVar will be accesible only by the class which declared it.
#protected
The iVar will be accesible by the class which declared it and by any subclasses. If you don't declare a directive this is used by default, and explains why you may think this is a way of declaring private variables.
#public
The iVar will be accesible from anwyehre.
#package
Accesible anywhere the app or static lib.
If you feel confused about some terms, don't worry. Most of the time there's no need to write the directive since #protected is the default one and it just work fine.
So, a iVars declaration will look like this:
#interface BIDMyController{
#protected
NSString *protectedString
#public
NSString *publicString
NSString *piblicString2 //This iVar is public since it's after de #public directive
}
I'm declaring variables on the interface file, although as you pointed out, they can be declared on the implementation file. The only difference is that declaring the iVars on the implementation file is a way of hiding private iVars. More about this here
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.
I see someone writes codes like this
#interface SomeClass:<NSObject>{
NSString * _iVar;
}
#property(nonatomic,retain)NSString *iVar;
and in implement file
#synthesize iVar = _iVar;
But I always like write codes like this:
#interface SomeClass:<NSObject>
#property(nonatomic,retain)NSString *iVar;
and in implement file
#synthesize iVar = _iVar;
They all works fine, and I can use an instance someClass to get iVar "someClass.ivar".I just know why?
You now don't even have to synthesize the iVars anymore. The latest Xcode will automatically create a backing instance variable for each property, with the property name prefixed with an underscore.
In Objective-C when you are using anything via "." (dot syntax), it is accessing property. You have declared and synthesize a property with name iVar, so you can access it with someClass.iVar.
When you are declaring a property, a variable is automatically created with it. So, even if you do not create a variable, it will be there.
To avoid ambiguity, people are creating properties and iVar with different names. So, they can identify if the variable is being used or a property is being used. In that case people let the compiler know that a particular variable is associated with a property by low way:
#synthesize iVar = _iVar;
If you want access variable directly outside the class instead of property, you should use "->" (arrow syntax).
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).