I am little confused about specifying strong, copy, or assign and not specifying them. We don't use NIB files. My colleague always use following - he says iOS detects it and use it automatically strong, weak etc.
#interface viewController : UIViewController
#property (nonatomic) UIImageView *imageView1;
#property (nonatomic) NSUInteger num;
#property (nonatomic) NSArray *array;
#end
I prefer following way doing it.
#interface viewController : UIViewController
#property (nonatomic, strong) UIImageView *imageView1;
#property (nonatomic, assign) NSUInteger num;
#property (nonatomic, copy) NSArray *array;
#end
Which one is better programming style? First option always have strong type as it defaults but I always specifies them explicitly.
As pointed out in earlier answers, in Objective C properties are by default,
atomic, strong/retain, readwrite --> For pointer types
atomic, assign, readwrite --> For primitive types
Property types weak, copy need to be explicitly specified by the programmer and in no way gets automatically decided.
What does each mean,
strong/retain referenced objects are kept alive in the memory until specified.
weak referenced objects will be destroyed when there is no strong reference. Typically used to reference delegate objects.
copy will create a shallow copy of the object getting assigned to the property.
assign/usafe_unretained(ARC) assigns the value. If used in case of pointer types this is an unsafe unretained assignment of the pointer. In ARC, typically use weak for pointer types because it will make the ivar=nil once weak referenced object is destroyed. assign in this case will lead to dangling pointer.
Personally, I prefer specifying property types even if it strong by default. This adds readability, which comes handy specially when profiling application for memory leaks or debugging crashes.
You can read more about properties here.
Hope that helps.
With ARC, strong is the default so the two are technically the same. From the Transitioning to ARC Release Notes:
__strong is the default. An object remains “alive” as long as there is a strong pointer to it.
Note that ARC will NOT automatically detect when something needs to be weak, however.
I tend to be explicit, like your second example, but I think it's mostly a matter of style/habit.
The default for a property is strongand for a variable is __strong too. In your current example the recommended property would actually be weak, but strong is acceptable too.
For properties of non-primitives you should no longer use assign, but rather unsafe_unretained. Practically they're the same, but the latter lets you know that you're using an object unsafely.
The copy property means that an object is copied (using the copy method) and not retained. It's recommended for classes such as NSString and NSArray, which have mutable forms. This is because you don't want to retain what you think is an immutable string but is actually being changed elsewhere.
The assign property declaration should be used only for primitive types and structs, e.g. int and CGSize.
Related
Can anyone tell me what is the difference among three property of delegation. I searched in google but did not get any satisfactory answer.
Please also tell me which is the best option and why?
#property (nonatomic, strong) id <GameAddViewControllerDelegate> delegate;
#property (nonatomic, weak) id <GameAddViewControllerDelegate> delegate;
#property (nonatomic, assign) id <GameAddViewControllerDelegate> delegate;
The difference is same as with strong, weak and assign specifiers.
Points to be noted : Any object never retains the delegate. Hence strong and retain should not be used.
weak and assign are allowed or even you can go with unsafe_unretained.
Why not to use retain?
Why use weak or assign?
Weak
weak applies to the delegate object (which has reference counts and
all the stuff), but weak references don't increase refcount. But once
the delegate object is deallocated (from anywhere in the code), any
weak reference to that object is set to nil. This is extremely useful,
because if you use only strong and weak references, you can't end up
with an invalid pointer (pointer to an already deallocated object).
Assign
assign is usually used for ints, floats and other non-object types.
You can of course assign an object reference to such a variable, but
if the object is deallocated, you will still have a pointer to it's
memory (which is garbage now, and will hurt you when you use it).
Strong
Strong will keep the object in the heap until it don't point to it
anymore. In other words " I'am the owner, you cannot dealloc this
before i'm fine with that same as retain" You use strong only if you
need to retain the object.
In case of delegation, weak preferred
You generally want to assign delegates rather than retain them, in order to avoid circular retain counts where object A retains object B and object B retains object A. (You might see this referred to as keeping a "weak reference" to the delegate.) For example, consider the following common pattern:
-(void)someMethod {
self.utilityObject = [[[Bar alloc] init] autorelease];
self.utilityObject.delegate = self;
[self.utilityObject doSomeWork];
}
if the utilityObject and delegate properties are both declared using retain, then self now retains self.utilityObject and self.utilityObject retains self.
Also see this detailed answer on stackoverflow
I'm a fan of not exposing class variables unless needed. In most objective-c code I see, the variables are declared as properties even if they are never to be used by an outsider.
#interface DetailViewController : UIViewController {
__weak IBOutlet UILabel *name;
}
vs
#interface DetailViewController : UIViewController
#property (weak, nonatomic) UILabel *name;
As a student of Software Engineering, this seams to me to be a pretty bad violation of principles such as encapsulation and could potentially lead to unwanted coupling in a large project.
I do understand the KVC aspects of using properties, but not why one would expose variables which are clearly only meant to be used internally in the class, such as the UILabel above.
Could someone explain why this is the preferred way when working with Objective-C on iOS?
Properties encapsulate the memory management (eg assign, retain, copy, strong, weak) of a iVar, while direct access to an iVar (instance variable) does not. This greatly reduces memory bugs.
Non-public properties can be declared at the top of the .m so there's no reason for them to be in the header:
#interface DetailViewController ()
#property (weak, nonatomic) NSString *name;
#end
Properties do create ivars that can be accessed. For the example above, with an explicitly synthesized property, the ivar would be named name while an implicitly synthesized synthesized property will have a leading underscore _name.
IBOutlets are declared in the header even though other classes don't need access to them as they are required so that Interface Builder connect to them and the nib loading system can populate the outlets. IBOutlets are most often going to be views, such as your UILabel.
Edit:
The previous paragraph about IBOulets is a legacy method required for Xcode 3 and earlier. However, newer versions of Xcode can use outlets defined in the implementation file just as the property above thanks to tighter integration of the InterfaceBuilder to the rest of the IDE.
What you see is an old style. Earlier Objective-C compilers required that you declare instance variables in the interface. However, by default they are #protected, so not everyone can just use them.
Current best practice is that you don't declare instance variables at all but use properties, unless you need to declare them (if you have a custom getter for a readonly property, or both custom getter and setter for a readwrite property, no instance variable is generated automatically), that you declare them in your .m file unless someone really needs to access them, that you declare properties and methods in your .m file unless someone needs to access them, and that you don't declare methods at all unless needed.
It's also quite common to declare a property as readonly in the header file, and redeclare it as read/write in the implementation.
In other words, hide what you can hide.
The first example indicates that you want to use the label as an outlet for a Xib or Storyboard. This answer sheds some light on that case: https://stackoverflow.com/a/1236985/171933
In general, however, you don't need to declare internal instance variables as properties. Actually, you can move them completely out of the header by putting them into your .m file like so:
#implementation DetailViewController
{
NSInteger _someValue;
UILabel *_someLabel;
}
That way you can really only keep the things in the header that should be visible to the outside. And those things would typically either be properties or plain old methods.
I know that if I use
#interface TPN : UIViewController{
IBOutlet UIView *testView;
}
#property (strong, nonatomic) IBOutlet UIView *testView;
I know that the first one is essentially a private variable that is only accessed within the class. and the second one "#property" is able to be accessed from an instantiated object. I find it odd in most tutorials that people tend to set properties when they are usually changing an outlet from within the class itself. Is there any guideline I should be following?
You no longer need to specify the ivar at all. Nor is there a need to use #synthesize.
Use a property, but make sure it is weak, not strong
#interface TPN : UIViewController
#property (weak, nonatomic) IBOutlet UIView *testView;
In the implementation you can now access the ivar as _testView.
For a private property (above is public) instead put the #property within a category in the implementation file:
#import "TPN.h"
#interface TPN ()
#property (weak, nonatomic) IBOutlet UIView *testView;
#end
#implementation TPN
....
You are right. If you are only going to use the instance variable inside the class, there is no point to make it a property. A property simply means a pair of getter/setter. If you don't need to do anything specially when getting/setting, you can just use the instance variable directly.
Prior to ARC, there was a side benefit to using properties everywhere, in that it was easier to do memory management for object pointers -- properties declared as retain would automatically release and retain for you when you set it, without you typing that code yourself like you would have to do with an instance variable directly. However, now in ARC, the compiler does that for you anyway when you assign, if it's a strong instance variable. So this benefit is now irrelevant.
I would suspect that a lot of the reason people use properties for outlets is because of perpetuation of that usage in almost all tutorials and examples (possibly due to the previous benefit with retain memory management), and they simply don't realize they can do something different.
Like a doop I'd been declaring Instant Variables (iVar) and then #property in the interface .h file for a while now.
#interface MainGameViewController : UIViewController {
UserFactorsViewController *userFactorsViewController;
UITableView *myTableView;
}
#property (nonatomic, retain) UserFactorsViewController *userFactorsViewController;
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
Under Automatic Reference Counting, should I just dispense with iVar and go all #property? Should I even have the word "retain" in property? What if I'm deploying for iOS 4.3, should I still use ARC?
Don't feel like a doop, even though the compiler will add ivars for you if you don't include them, many people still declare them (many book authors as well) to make the code a little bit easier to read (easier to distinguish between ivar and property).
When creating a property now, Apple wants you to think in terms of Object Graphs, so do some research on "strong" and "weak" property attributes instead of retain and releases.
Also, iOS 4 is setup as a target for ARC so you should be ok. But I believe if you wanted to support iOS 3.0 you would have to manually manage retain and releases as before.
Objective-C for iPad, Where do you put IBOutlet? In instance variable declaration or #property declaration? Is there a difference at all?
IBOutlet can be a marker on ivars or a property declaration.
There is a slight difference. IBOutlet properties go through access methods whereas IBOutlet ivars are direct ivar access.
The major difference is that if the IBOutlet property is retained, you'll have to release it in -dealloc whereas you typically need not do anything with an IBOutlet ivar. The upside of IBOutlet property is that you get all the useful features of properties.
Both are valid, even if it's usually recommended to put it on a property.
The difference with a property is that it's available from the outside, and that getter/setter methods are used.
That also allows property qualifiers, like non-atomic and retain, usually set for the IBOutlets.
mmalc (who is definitely a reputable source) says that the current best-practice is putting it on the #property declaration. He gives details (along with some cavets) in his answer to this quiestion
Both are valid I suggest you to use #property
I do both, and synthesise it in the .m file. I'm not 100% that they're both essential, but it doesn't hurt.