Using weak with readonly property? - ios

Should one use
#property (nonatomic, weak, readonly)
or
#property (nonatomic, readonly)?
Weak has the advantage of nil-ing out the instance if it gets deallocated, but is readonly implying weak? Should one explicit declare a property as weak if it want the weak behaviour?

If you want to keep a pointer to an object that you don't own but want it to be valid only as long as it exists, then you want to use a weak pointer because when it gets deallocated by the owner, your pointer will automatically get set to nil and won't be pointing to memory that it shouldn't be.
These both have differnect meaning, readonly doesn't make any differnce if it is weak or strong.
#property (nonatomic, weak, readonly)
#property (nonatomic, readonly)
You can also find some reference here.

Weak or strong is by no means related to readonly or readwrite. None implies the other.
A strong relation takes ownership. A weak does not but it receives the service of being nullified upon deletion of the related object.
Readonly suppresses a setter (afaik). The property cannot be changed from outside its class.
Readwrite (wich is the default if none is stated) allows changes to the property.
That's basically it. That are two settings which are not related to each other. They work in all thinkable comibnations.

Related

Difference between different property declaration in the delegate case

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

Correct way to declare properties

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.

iOS SDK - Correct methodology in making connections with an outlet?

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.

Arc and nilling property through weak pointer

I have a situation here where I would want to nil a strong property with a weak reference property. My class looks like this;
#interface MyClass()
#property(nonatomic, strong) Man *man;
#property(nonatomic, strong) Women *women;
#property(nonatomic, weak) Person *passedPerson
#end
I pass this object everytime to the new view controller, sometimes I pass men while some time I pass women but I always keep track of the passed object in weak reference, ie. passedPerson.
Now, when the viewcontroller return, based on the currently passed object, I would like to nil it through the weak reference pointer. Is it even possible ? This is not my exact situation but I have many objects like this which needs to be nilled out when I finish with them in the presenting view controller. How can this be done ?
Weak reference is used when you need to break a reference cycle. In the example you show, there is no reference cycle. But I assume you want to keep the passedPerson.
You could use weak references to man and women and keep a strong reference on the passedPerson. Then you can nil out the passedPerson as you are finished with them.

IOS: property without ARC

I have a project with ARC but I disable it and now I have problem with properties as:
#property (weak, nonatomic) IBOutlet UIView *frame;
now I have an error for "weak", what kind I can replace? retain?
thanks
The closest thing to weak under manual reference counting is assign. Keep in mind, that unlike weak under ARC, the value of assign properties is not automatically zeroed when the instance pointed to by the property is deallocated. So, you need to be careful to discard assign references to objects before they're deallocated.
Why did you disable ARC?
You should replace it with assign. And strong with retain. retain means the reference counter will be increased for every object stored there. And if you replace weak with retain you can get reference cycle and leak some memory.

Resources