Objective-C properties using ARC - ios

Im just about to refactor my current iOS project to use ARC. And after previewing the changes to migrate my current code to ARC using the "Refactor to ARC" tool i xCode, i can see my current code conventions probably not suited for ARC. Because it adds alot of __weak / __strong etc to my ivars.
Heres how my current conventions are:
i define all instance variables as private or protected ivars. and all public variables i create a #property for.
#interface TestClass
{
#private
NSMutableArray* mArray;
NSString* mString;
BOOL mMyBoolean;
}
#property (retain, nonatomic) NSString* string; // public
#end
All objects i always back with a #property, to avoid dealing with release / retain so if i have a private variable that is a reference, i just create a category in the implementation. Struct (like mMyBoolean) i just leave define as a ivar.
#interface TestClass()
#property (retain, nonatomic) NSmutableArray* mArray;
#end
#implementation TestClass
#synthesize string = mString;
#synthesize mArray;
#end;
But because the new ARC is taking care of retain / release i properly dont need private variables to be backed by #property.
So what code conventions would be more appropriate? Ive been thinking about just defining properties in the interface like this:
#interface TestClass
{
#private
NSMutableArray* mArray;
BOOL myBoolean;
}
#property (strong, nonatomic) NSString* string;
#end
#implementation TestClass
#synthesize string;
#end
And dont use category properties for private properties. (also i removed the "m" prefix) and i dont define the backed ivar that #property should use, instead i just let xcode use its autogenerated?.

This is more of a style question, so...it's hard to answer objectively, but I will throw in my two cents. There is not anything wrong with what you are doing as far as I can see. If your goal is to see what you can do to have cleaner code, then I will share my naming conventions (though one man's junk is another man's treasure, so if you don't like it then...well tough haha, you don't have to take anything away from it).
1) iVars start with m and are never public.
2) Property synthesized to a variable name starting with underbar (_), no explicit backing variable unless I need inherited classes to be able to modify a read only variable internally, in which case I need to move it to the public interface (and I still name it with an underbar to indicate to myself that it is a property variable). Properties are meant to expose some info through an interface, but since the implementation has access to everything it doesn't make sense and I never use properties in private interfaces except for the following case:
3) Properties that lazy load, or otherwise have logic outside of simply assigning to a variable. In this case, if I only override the getter or setter (not both) I will still synthesize to (_) and override the desired method (no need for explicit variable). If I override both, I don't synthesize then obviously I need an explicit backing variable (don't forget to call the KVO methods ^^).
There is no "right" way to do this kind of stuff I imagine...the only guidelines that seems to be universal are
1) Do it in a way that you and your team can understand easily
2) Do it consistently
3) In the case of an API, do it in a way that is easily understandable from looking at only the header files.

Related

Difference between variables in interface Object() {} and #implementation Object #end

I'm starting my adventure with Objective-C and iOS and I've got one thing that I don't know how to use correctly and this is literally blowing my mind.
Many tutorials have private class variables in .m files defined like this:
#interface ViewController (){
#property (nonatomic, strong) NSMutableArray *myArray;
}
or like this:
#implementation ViewController
NSMutableArray *myArray;
#end
In the first example I can use _myArray instead of self.myArray, which I like, but should I put all my private variables in interface files? What's the difference between those two variables? When should I use one instead of another, and which is safer?
The difference is that:
_myArray is instance variable.
self.myArray is calling a getter method on your object.
Using self.myArray = nil makes the variable go through its setter and therefore release the object when ARC is not used).
If the property is declared with atomic (default value) which means access the variable is thread-safe with the cost of performance
nonatomic property means race condition can happen when access the variable or property from multiple threads.
In general, use atomic for object shared with multiple threads and nonatomic for UI or not shared object.
Attention, you will get compiler error with your code:
#interface ViewController (){
#property (nonatomic, strong) NSMutableArray *myArray;
}
-> you must move #property... outside of {} of your header.
#interface ViewController (){
//
}
#property (nonatomic, strong) NSMutableArray *myArray;
A couple of thoughts:
The first example is not syntactically correct. You probably meant the following, which defines a declared property inside the class extension:
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *myArray;
#end
A property will:
Synthesize an instance variable called _myArray (or if you specify a #synthesize directive, you can control the name of this instance variable);
Synthesize accessor methods, notable a myArray getter that retrieves the value and a setMyArray setter that sets the value;
Provide other features such as key-value coding, etc.
On the other hand, the following declares a global variable:
#implementation ViewController
NSMutableArray *myArray;
#end
Globals are a very different beast, shared amongst all of the various instances of this class (and across the whole app). In this case (some mutable array used by a class instance), a global is likely not what you intended.
If you intended to define an instance variable, you could do:
#implementation ViewController
{
NSMutableArray *myArray;
}
#end
Or, perhaps better than defining this ivar in the #implementation like that, one would generally define them within the class extension's #interface:
#interface ViewController ()
{
NSMutableArray *myArray;
}
#end
I suspect you didn't actually intend to compare the global variable to a instance variable (ivar) or property, but rather were asking the rationale for privately using a property vs. ivar within a class implementation:
Bottom line, within a particular class, using ivars is a perfectly acceptable practice, but many of us use private properties defined in class extensions. The overhead is minimal and it abstracts the code away from the implementation details of the ivar. For example, you can customize one or more of the accessor methods at some future date and have minimal impact on the rest of the class implementation. But it's a matter of personal preference.
#property creates your setters and getters the other one does not.
yes, #property is automatically creates setter and getter.
additionally, you can setting property's attribute.
(read-only/readwrite, nonatomic/atomic, strong/weak.. etc)
accessing instance variable by getter & setter(instead of using pointer to direct access) make data encapsulated.
it is common and important concepts of Object-Oriented Programming.
read this for understanding.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
sorry for poor english. :<

Objective-C member variable vs property in source file

I understand the difference between member variable and property in Object-C, but there is one thing make me confused. See the following code.
test.h
#interface test : NSObject
#end
test.m
#interface test()
{
NSString *memberStr;
}
#property (nonatomic, strong) NSString *properyStr;
#end
As showed, the memberStr and propertyStr can't be see by outside. I want to know what is the difference between them. Because I don't how to chose the solution when i want to use local variable.
Thanks!
properyStr will have the getters and setters generated automatically.
you can define custom setter for propertyStr as below. When you use self.propertyStr, it will create a default object for you. It will be useful for initialising objects like NSMutableArray, NSMutableDictionary etc.
- (NSString *)properyStr
{
if(_propertyStr == nil)
{
_propertyStr = #"";
}
return _propertyStr;
}
memberStr will not have these options.
I understand the difference between member variable and property in Object-C
I'm not sure that you do.
A member variable is a variable that's visible only within the scope of instance methods.
A property is some attribute of the class that can be set or get. The compiler will write appropriate getters and, optionally, setters, and will organise storage for itself, unless you override any of those things.
Both member variables and properties can be declared either in the #implementation or in the #interface.
A member variable can never be accessed directly by unrelated classes, regardless of where it was declared. If it's in the #interface then it can be accessed by subclasses.
A property can always be read and, optionally, written by any other class, regardless of where it was declared. External classes can use the key-value coding mechanism even if the #property isn't visible to them.
Questions you may therefore be likely to ask:
Q) Why would I put a member variable into the #interface?
A) It's unlikely you would. It will expose it to subclasses but usually wanting to do so is a design flaw. However, in olden times you had to put all member variables into the #interface for reasons of how the old Objective-C runtime worked. So older code and stuck-in-their-ways programmers will still sometimes follow this pattern.
Q) Why would I declare a property visible only to the #implementation?
A) It's unlikely you would. However in olden times this was the only way to create member variables that weren't visible in the #interface so was the way people did most member variables for a brief period. Similarly, you could declare something, say retain, then use the getter/setter and assume correct memory management was going on, so it acted as some syntactic sugar in the days before ARC was introduced. As with the previous answer, there are therefore some people who still do so through habit and some code that still does so on account of being older. It's not something you'd often do nowadays.
EDIT: a better summary: properties adjust your class interface. Member variables adjust its implementation. In object-oriented programming you should be thinking of the two things as entirely disjoint.
One of the main purposes of object-oriented programming is to have a bunch of discrete actors that say "I can do X" with exactly how they do it being nobody else's business.
A property says what a class can do. A member variable is for the benefit of how the class does it.
Semantically they're completely separate issues.
First of memberStr is an instance variable or ivar.
There is no need to have memberStr any more if you have a property setup for this all you need is.
#interface test()
#property (nonatomic, strong) NSString *properyStr;
#end
The reason for this is that the ivar will be automatically created for you along side the setter and getter methods.
The only difference between declaring the property in the implementation files (.m) interface over the interface file (.h) is that it will be private to this class only. There are many advantages for having this such as maybe you don't want anything outside of the class to know about it but you want the property to be in scope for this class still. One thing that they are used for in this manner is when you have a readonly property declared public but you still want the setter to be in scope for this class. So you may have something like
.h
#interface MyObject : NSObject
// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
#property (nonatomic, readonly) NSString *firstName;
#end
.m
#interface MyObject()
// But we still want to use the setter for this class only.
#property (nonatomic, strong) NSString *firstName;
#end
Otherwise except for being private to that class only; having the property in the implementation file (.m) will be the exact same as having it in the interface file (.h) they will act and do the same thing.

Should I declare variables in interface or using property in objective-c arc?

approach 1:
#interface MyController : UIViewController {
UILabel *myText;
}
#property (nonatomic, strong) UILabel *myText;
approach 2:
#interface MyController : UIViewController
#property (nonatomic, strong) UILabel *myText;
approach 3:
#interface MyController : UIViewController {
UILabel *myText;
}
I have read some articles talking about this kind of stuff but I still do not really realize which approach I have to adopt.
I also found that someone said approach 1 is a old way so I would like to know the best practice for ios sdk 6 using ARC.
I know that declaring variables using property is a easy way for generating getter and setter and someone suggested using it. However, I would like to ask in case a variable is not for calling by another class, is it necessary for the variable using property? and set it as private variable inside the interface? Or is it better for a variable only declaring inside the interface? I would like to learn the best practice so please forgive me if this is a silly question.
Moreover, some developers write #synthesize in this way
#synthesize myText=_myText;
but some write this:
#synthesize myText;
I would also want to know the difference and which one is preferable?
Thank you very much!
The most modern way1:
whenever possible, declare properties
don't declare iVars separately 2
don't #synthesize 3
locate as few properties as possible in you .h file 4
locate as many properties as possible in a class extension in your .m file 5
1 As of Xcode 4.5.2. Most of this applies back to 4.4, some of it won't compile on 4.2 (the last version available under Snow Leopard). This is preprocessor stuff, so it is all compatible back at least to iOS5 (I haven't tested on iOS4 but that should also be OK).
2 There is no point in declaring an iVar as well as a property. I am sure there are a few obscure cases where you would want to declare iVars instead of properties but I can't think of any.
3 Xcode will create an iVar with the same name as the property, preceded by an _underscore. If you (rarely) need some other kind of behaviour, you can manually #synthesize property = someOtherName. #vikingosegundo links us to this article on dynamic ivars, which is a use case for #synthesize. #RobNapier comments that you do need to #synthesize iVar = _iVar (bizarrely) if you are creating your own getters (readonly) and setters (read/write) for a property, as in this case the preprocessor will not generate the iVar for you.
4 The general rule with your interface: keep it as empty as possible. You don't actually need to declare your methods now at all, if they are for private use. If you can get the code to work without an interface declaration, that's the way to go.
5 This is an #interface block in your .m file, placed above your #implementation:
#TestClass.m
#interface TestClass()
//private property declarations here
#end
#implementation TestClass
...
You may also want to use #synthesize if you like a nice table of contents of your #synthesized properties that you can refer to and comment for clarity and organization.
Also, an #synthesize allows you to set a breakpoint on the property and trap when its value is changed.
When the compiler does everything for you, you end up being distanced from what is really happening and ignorant to it. However, not having to type out everything yourself all the time is also nice.

Instance variables, properties and transition to ARC

Finally I'm transitioning to ARC. Sounds too late but all my projects have retrocompatiilty to 3.0 (any news about App Store unsupporting?) so I can't use it. But now I'm working in a new project with base deployment in iOS 5 so I'm using ARC.
My question is so simple. I'm used to declare private instance variables and public properties. For example:
#interface MyClass : NSObject {
#private
Var *aVar_;
Var *anotherVar_;
}
#property (nonatomic, readonly) Var *aVar;
#end
#implementation MyClass
#synthesize aVar = aVar_;
#end
Inside the class I work with instance variables, not properties.
But now I'm trying to avoid instance variables because I think there are not neccessary and redundant if I use proeprties, and I read time ago that is better to use properties instead of instance variable, but I'm not sure. That class now seems like that
#interface MyClass : NSObject
#property (nonatomic, readwrite, strong) Var *aVar;
#end
#interface MyClass()
#property (nonatomic, readwrite, strong) Var *anotherVar;
#end
#implementation MyClass
#synthesize aVar = aVar_;
#synthesize anotherVar = anotherVar_;
#end
In this case I'm still using instance variables (underscored) to manage my data because is less verbose and ARC takes into account all memory issues, but I don't know if that is correct.
Also I have another question. The property of aVar in the first chunk of code is readonly but if I use only properties I have to make that property readwrite. If I want to make the public property readonly, do I have to declare a public readonly property in the #interface and a private readwrite in private #interface?
Thank you so much.
The answer to your questions is somewhat complex, but generally you have the swing of it.
Since ARC does all the memory management for you, its often simpler to just use an ivar (private to the class, declared in the implementation) for your internal needs. In that case all usages just use the name.
With properties, you can as of Xcode 4.4 let Xcode synthesize the setter and getter, as well as the ivar. Auto-synthesized ivars are created with a leading "_" character.
You can define a property as readonly in the implementation, leave it as readonly, and set it in your code as '_foo = ....'. [Many on this site would consider this a bad practice, my point is you can do it.]
Xcode 4.4 has a warning titled "Implicit Synthesized Properties" with a default of NO. This creates a warning if you do not provide a #synthesize statement for each property, even though it will do the synthesis anyway.
Personally, I use ivars whenever I can, and only define properties when I need to either make something public to other classes, or I have categories declared in multiple files (in which case I put the interface declaration of the class extension in its own file along with properties defined in it.)
With the new Objective-C update you don't even need to synthesize the property. All you need to do is declare #property (strong, nonatomic) Var *aVar; and the compiler will automatically add the synthesizing, backing the self.aVar property with an _aVar instance variable.
If you declare a property, your implementation should generally use that property even though ARC reduces some of the memory management errors.
In init some prefer to avoid using properties because doing so might trigger KVO on an object (self) that is only partially initialized.

Is it a good practice to declare properties in implementation file, If yes, what's the use?

Is following code, a good programming practice in objective-C ?
#import "Custom.h"
#interface Custom ()
#property (nonatomic, retain) UILabel *label;
#end
#implementation Custom
#synthesize label;
- (void) dealloc {
[label release];
[super dealloc];
}
#end
The idea behind this is that all properties you declare in your header file, are visible and accesible for everyone outside that class.
To respect the encapsulation principle of OOP, you want to make the scope of certain members of your class as private as possible. So all those members that only your class will use, should be hidden to "the outside world". This can be done by declaring a special type of category called "extension" (it can't have a name, it's declared as #interface Class () ), and the properties inside that extension (along with private method declaration if you want as well)
As to the question whether it's a good practice, that may be discussed among different developers. To me, it is since it's good OOP practice, and also because it helps keeping your header file as clean as possible (and so making it easier for other developers to see what "services" your class provides)
I like to do this to create private interfaces. If a property is only used in your implementation, not in collaboration with other objects, it should not pollute the header (which defines the public interface). You can also hide private protocol implementations this way:
#interface YourClass () <UIAlertViewDelegate>
This way the users of your class don’t have to know that you have an UIAlertView buried somewhere in your implementation.
What could be considered a downside is that your subclasses can no longer access the “private” properties. You have to either move their declaration to the header file (making them public), or create a special “protected” header.
Another option worth mentioning in this context is declaring private variables in the #implementation directive:
#implementation YourClass {
NSString *foo;
NSUInteger bar;
}
These are not statics, they are regular instance variables.
You would want to define label in your header for later use through out other methods in your #implementations. For example, create that label in your viewDidLoad, and you can change it throughout the other methods..

Resources