custom class initializers with ARC - self.name or name? - objective-c

when defining a Person class with ARC,
should i use self.fullname or just fullname in the initializer?
if i use fullname will the passed strings be retained?
if i use self.fullname i must define a setter or a property? should i use strong?
coming from a pre ARC way of thinking, i'm trying to wrap my head around the changes ARC suggests.

With ARC, these behave the same way, except that self.fullname will pass through the setter. The default setter will give you KVO-compliance. But otherwise, there is no difference.
Yes they will, if the pointers have been declared strong.
To use self.fullname = ... you must define a setter. For NSStrings and other classes which have mutable variants, it is usually recommended to use (copy).

In initializers, I'd advise against invoking any methods on self, because the object is in that unusual state where it lacks self-consistency. For the simple example you give, it doesn't make a difference right away. But if you later define your own -setFullname: method that reads or writes any other part of your object, invoking self.fullname = from your initializer will cause problems because the object isn't fully-formed yet.

I think the available answers need some clarification.
The long answer to your question
Look at this header:
Person : NSObject {
NSString *name; // better to call this _name to not confuse it with the property
// and even more better to not use an ivar, but only a property
}
#property (strong) NSString *name;
You have an instance variable. Usually you'd call your ivar the same as the property with an underscore, but often you'll find the ivar and the property have the same name.
It is also possible to only declare a property, in this case, the compiler will automatically insert an ivar with an underscore for you!
Now it is important to understand, that there is one major difference between name = #"John Smith" and self.name = #"John Smith", the first one directly sets the instance variable (aka _name = #"John Smith", disregarding memory management and (without ARC) creating a leak if the former value was not nil. Using the self-dot-syntax (self.name) uses the automatically generated accessor (=setter method), which respects the chosen memory management (typically retain or strong or copy).
Before properties and before ARC an object setter would have looked like this:
-(void)setName:(NSString*)newName {
if(newName != name) {
[name release];
name = newName;
[newName retain];
}
}
that means, the old iVar value is released and the new iVar value retained. All balanced and fine.
Now, with ARC and synthesized accessors (properties), you do not have to care about all this. While Properties synthesize acessors, ARC synthesizes and balanced retain/release calls based on an analysis of your code. So ARC and properties are not necessarily requiring each other, because they synthesize different aspects (note for example the different syntax "__weak" at the ivar declaration and "(weak)" at the property declaration?). But it's useful to know how it used to work, because now you'll see that there is a major difference between
name = #"John Smith"; // directly access ivar, the old value is never released
// your program is leaking if you're not using ARC
and going through the synthesized accessor
self.name = #"John Smith"; // old ivar released, new ivar set, all okay
The short answer to your question
do not use an ivar and a property if there is no need for both
self.property = newValue sets the new value by its setter method
ivar = newValue sets the new value directly, bypassing any setter method
it is definitely recommended to use the accessors and to not set ivars directly if there is a setter method (in other words: if you have a property, use its setter by calling self.property = newValue)

Related

When to use strong, weak, retain etc? [duplicate]

There are two new memory management attributes for properties introduced by ARC, strong and weak.
Apart from copy, which is obviously something completely different, are there any differences between strong vs retain and weak vs assign?
From my understanding, the only difference here is that weak will assign nil to the pointer, while assign won't, which means the program will crash when I send a message to the pointer once it's been released. But if I use weak, this won't ever happen, because message send to nil won't do anything.
I don't know about any differences between strong and retain.
Is there any reason why should I use assign and retain in new projects, or are the kind of being deprecated?
After reading so many articles Stackoverflow posts and demo applications to check variable property attributes, I decided to put all the attributes information together:
atomic //default
nonatomic
strong=retain //default
weak
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
Below is the detailed article link where you can find above mentioned all attributes, that will definitely help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
1.strong (iOS4 = retain )
it says "keep this in the heap until I don't point to it anymore"
in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain"
You use strong only if you need to retain the object.
By default all instance variables and local variables are strong pointers.
We generally use strong for UIViewControllers (UI item's parents)
strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.
Example:
#property (strong, nonatomic) ViewController *viewController;
#synthesize viewController;
2.weak
-
it says "keep this as long as someone else points to it strongly"
the same thing as assign, no retain or release
A "weak" reference is a reference that you do not retain.
We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only needs to exist as long as the parent object does.
a weak reference is a reference that does not protect the referenced object from collection by a garbage collector.
Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil
Example :
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#synthesize myButton;
Strong & Weak Explanation, Thanks to BJ Homer:
Imagine our object is a dog, and that the dog wants to run away (be
deallocated).
Strong pointers are like a leash on the dog. As long as you have the
leash attached to the dog, the dog will not run away. If five people
attach their leash to one dog, (five strong pointers to one object),
then the dog will not run away until all five leashes are detached.
Weak pointers, on the other hand, are like little kids pointing at the
dog and saying "Look! A dog!" As long as the dog is still on the
leash, the little kids can still see the dog, and they'll still point
to it. As soon as all the leashes are detached, though, the dog runs
away no matter how many little kids are pointing to it.
As soon as the last strong pointer (leash) no longer points to an
object, the object will be deallocated, and all weak pointers will be
zeroed out.
When we use weak?
The only time you would want to use weak, is if you wanted to avoid retain cycles
(e.g. the parent retains the child and the child retains the parent so neither is ever released).
3.retain = strong
it is retained, old value is released and it is assigned retain specifies the new value should be sent
retain on assignment and the old value sent -release
retain is the same as strong.
apple says if you write retain it will auto converted/work like strong only.
methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
4.assign
assign is the default and simply performs a variable assignment
assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
From the Transitioning to ARC Release Notes (the example in the section on property attributes).
// The following declaration is a synonym for: #property(retain) MyClass *myObject;
#property(strong) MyClass *myObject;
So strong is the same as retain in a property declaration.
For ARC projects I would use strong instead of retain, I would use assign for C primitive properties and weak for weak references to Objective-C objects.
nonatomic/atomic
nonatomic is much faster than atomic
always use nonatomic unless you have a very specific requirement for atomic, which should be rare (atomic doesn't guarantee thread safety - only stalls accessing the property when it's simultaneously being set by another thread)
strong/weak/assign
use strong to retain objects - although the keyword retain is synonymous, it's best to use strong instead
use weak if you only want a pointer to the object without retaining it - useful for avoid retain cycles (ie. delegates) - it will automatically nil out the pointer when the object is released
use assign for primatives - exactly like weak except it doesn't nil out the object when released (set by default)
(Optional)
copy
use it for creating a shallow copy of the object
good practice to always set immutable properties to copy - because mutable versions can be passed into immutable properties, copy will ensure that you'll always be dealing with an immutable object
if an immutable object is passed in, it will retain it - if a mutable object is passed in, it will copy it
readonly
use it to disable setting of the property (prevents code from compiling if there's an infraction)
you can change what's delivered by the getter by either changing the variable directly via its instance variable, or within the getter method itself
As far as I know, strong and retain are synonyms, so they do exactly the same.
Then the weak is almost like assign, but automatically set to nil after the object, it is pointing to, is deallocated.
That means, you can simply replace them.
However, there is one special case I've encountered, where I had to use assign, rather than weak. Let's say we have two properties delegateAssign and delegateWeak. In both is stored our delegate, that is owning us by having the only strong reference. The delegate is deallocating, so our -dealloc method is called too.
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething];
[delegateAssign doSomething];
}
The delegate is already in deallocation process, but still not fully deallocated. The problem is that weak references to him are already nullified! Property delegateWeak contains nil, but delegateAssign contains valid object (with all properties already released and nullified, but still valid).
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething]; // Does nothing, already nil.
[delegateAssign doSomething]; // Successful call.
}
It is quite special case, but it reveal us how those weak variables work and when they are nullified.
Clang's document on Objective-C Automatic Reference Counting (ARC) explains the ownership qualifiers and modifiers clearly:
There are four ownership qualifiers:
__autoreleasing
__strong
__*unsafe_unretained*
__weak
A type is nontrivially ownership-qualified if it is qualified with
__autoreleasing, __strong, or __weak.
Then there are six ownership modifiers for declared property:
assign implies __*unsafe_unretained* ownership.
copy implies __strong ownership, as well as the usual behavior of copy semantics on the setter.
retain implies __strong ownership.
strong implies __strong ownership.
*unsafe_unretained* implies __*unsafe_unretained* ownership.
weak implies __weak ownership.
With the exception of weak, these modifiers are available in non-ARC modes.
Semantics wise, the ownership qualifiers have different meaning in the five managed operations: Reading, Assignment, Initialization, Destruction and Moving, in which most of times we only care about the difference in Assignment operation.
Assignment occurs when evaluating an assignment operator. The
semantics vary based on the qualification:
For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores.
For __weak objects, the lvalue is updated to point to the new pointee, unless the new pointee is an object currently undergoing deallocation, in which case the lvalue is updated to a null pointer. This must execute atomically with respect to other assignments to the object, to reads from the object, and to the final release of the new pointee.
For __*unsafe_unretained* objects, the new pointee is stored into the lvalue using primitive semantics.
For __autoreleasing objects, the new pointee is retained, autoreleased, and stored into the lvalue using primitive semantics.
The other difference in Reading, Init, Destruction and Moving, please refer to Section 4.2 Semantics in the document.
To understand Strong and Weak reference consider below example,
suppose we have method named as displayLocalVariable.
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
}
In above method scope of myName variable is limited to displayLocalVariable method, once the method gets finished myName variable which is holding the string "ABC" will get deallocated from the memory.
Now what if we want to hold the myName variable value throughout our view controller life cycle. For this we can create the property named as username which will have Strong reference to the variable myName(see self.username = myName; in below code), as below,
#interface LoginViewController ()
#property(nonatomic,strong) NSString* username;
#property(nonatomic,weak) NSString* dummyName;
- (void)displayLocalVariable;
#end
#implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.username = myName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Now in above code you can see myName has been assigned to self.username and self.username is having a strong reference(as we declared in interface using #property) to myName(indirectly it's having Strong reference to "ABC" string). Hence String myName will not get deallocated from memory till self.username is alive.
Weak reference
Now consider assigning myName to dummyName which is a Weak reference, self.dummyName = myName;
Unlike Strong reference Weak will hold the myName only till there is Strong reference to myName.
See below code to understand Weak reference,
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.dummyName = myName;
}
In above code there is Weak reference to myName(i.e. self.dummyName is having Weak reference to myName) but there is no Strong reference to myName, hence self.dummyName will not be able to hold the myName value.
Now again consider the below code,
-(void)displayLocalVariable
{
NSString myName = #"ABC";
NSLog(#"My name is = %#", myName);
self.username = myName;
self.dummyName = myName;
}
In above code self.username has a Strong reference to myName, hence self.dummyName will now have a value of myName even after method ends since myName has a Strong reference associated with it.
Now whenever we make a Strong reference to a variable it's retain count get increased by one and the variable will not get deallocated retain count reaches to 0.
Hope this helps.
Strong:
Property will not Destroy but Only once you set the property to nil will the object get destroyed
By default all instance variables and local variables are strong pointers.
You use strong only if you need to retain the object.
We generally use strong for UIViewControllers (UI item's parents)
IOS 4 (non-ARC) We Can Use Retain KeyWord
IOS 5(ARC) We Can Use Strong Keyword
Example:
#property (strong, nonatomic) ViewController *viewController;
#synthesize viewController;
Weak
By Default automatically get and set to nil
We generally use weak for IBOutlets (UIViewController's Childs) and delegate
the same thing as assign, no retain or release
Example :
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#synthesize myButton;
The differences between strong and retain:
In iOS4, strong is equal to retain
It means that you own the object and keep it in the heap until don’t point to it anymore
If you write retain it will automatically work just like strong
The differences between weak and assign:
A “weak” reference is a reference that you don’t retain and you keep it as long as someone else points to it strongly
When the object is “deallocated”, the weak pointer is automatically set to nil
A "assign" property attribute tells the compiler how to synthesize the property’s setter implementation

Can anyone explain the synthesize process when using Objective-C?

I realize that it automatically creates a setter & getter for you but I'm uncertain how the setter actually "looks".
Also, why is it recommended that we say #synthesize someObject = _someObject; instead of just #synthesize someObject;?
Easy bit first: you don't need to #synthesize at all any more. If you have an #property and you don't synthesise it then one is implied, of the form #synthesize someObject = _someObject;. If you left off the = _someObject then you would have the same thing as #synthesize someObject = someObject;. The underscore version is therefore preferred because Apple has swung back to advocating underscores for instance variables and because it's consistent with the implicit type of synthesise.
The exact form of setter and getter will depend on the atomic, strong, unsafe_unretained, etc flags but sample nonatomic strong setter, pre-ARC is:
- (void)setProperty:(NSString *)newPropertyValue
{
[newPropertyValue retain];
[_property release];
_property = newPropertyValue;
}
Note the retain always occurs before the release. Otherwise the following (which you would arrive at in a roundabout fashion rather than ever writing directly):
self.property = _property;
Would lead to _property potentially being deallocated before it was retained.
A sample getter (also pre-ARC) is:
- (NSString *)property
{
return [[property retain] autorelease];
}
The retain ensures that the return value will persist even if the object it was queried from is deallocated. The autorelease ensures you return a non-owning reference (ie, the receiver doesn't explicitly have to dispose of the thing, it can just forget about it when it's done). If the thing being returned is immutable but the instance variable is mutable then it's proper form to copy rather than retain to ensure that what you return doesn't mutate while someone else is holding onto it.
Check leture 3 of iPad and iPhone Application itunes
_someObj replace a memory location for store your object(a pointer).
Xcode 4 auto #synthesize anyObject = _anyObject; -> So you don't need to write #synthesize anymore.
If you have some other object or _anyMemoryLocation write before in your.m file, you can use #synthesize yourObj = _anyMemeryLocation if you don't want rewrite all name in your.m file.
Setter and getter 2 methods use to set or get your object's value outside or inside your class:
-(void)setObject:(ObjectType *) object;
-(void)getObject:(ObjectType *) object;
The key nonatomic auto generate setter and getter for you.
If you want to implement more method went setObject, you can rewrite it in your.m file
-(void)setObject:(ObjectType *) object{
_object = object; //rewrite setter can done anywhere in your.m file
//Add more method
}

Objective C: Differentiating iVars and Accessors

#interface RandomObject : NSObject
{
NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point.
}
#property (nonatomic, strong) NSString *someObject;
#end
#implementation RandomObject
#synthesize someObject;
#end
Given the code above and Xcode 4.3 is used (hence, no auto-synthesizing), here is my question.
The property/synthesize will create accessors for someObject, namely getter and setter. So if I want to assign a value to someObject, I can do this.
self.someObject = #"Tomato"; // [self setSomeObject: #"Tomato"];
If my understanding is correct, self will send #"Tomato" to setSomeObject method. But what if you do this?
someObject = #"Tomato"; // or maybe _someObject = #"Tomato" if you are doing auto-synthesizing
Directly accessing an iVar object seems like a bad idea, but since someObject is a private variable, within the same class you have access to that, right?
I understand why you would need to use self.someOject if you want to manipulate someObject from another class. But why is it that you'd need to do the same even though you are still in the same class. Why is it that it's a bad idea to directly access iVar.
Generally speaking accessors have more pros than cons and I use them everywhere I can.
The main issue is that every place you reference the ivar directly is another potential place your code will need to change.
For example imagine you have referenced someObject in multiple places throughout your class. Then the requirements change and now you decide that when the value of someObject is assigned you need to so some other work. Due to the fact that you have accessed the ivar directly throughout the class you now have to either duplicate this new code everywhere you assign someObject or refactor. If you was using an accessor you just have one piece of code to change
- (void)setSomeObject:(id)anObject
{
if (anObject != someObject) {
someObject = anObject;
[self doSomeWork];
}
}
You can have the same issue with the getter - imagine you store an array of objects in someObjects - this works great but then later down the line you decide that you don't actually need to store someObjects as it can be dynamically computed from other values. If you have directly accessed the ivar everywhere then this becomes a big chore. If you stick to abstracting someObject behind a getter then all you now have to do is
- (NSArray *)someObjects
{
return [self calculateSomeObjects];
}
This is exactly the idea with non-ARC code, which puts the memory management of the ivar in one place (behind accessors) so that you do not have to litter your code with repetitive code.
The property does more than just assigning an object to the ivar.
If you don't use ARC, the property will auto-generate retain/release code to handle memory management. Just calling someObject = #"Tomato" creates a memory leak (if someObject is assigned)
If your property is atomic, the property will provide thread safety, while accessing the ivar would not be thread safe.
See https://stackoverflow.com/a/589348/1597531 for examples of auto-generated property code.

Objective-C ARC Should constructor set Instance Variable or Property? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should I refer to self.property in the init method with ARC?
I'm new to Objective-C and still trying to get my head around everything that's different (from C# and C). I'm using ARC in my project.
Say I've got a constructor like so:
-(id)initWithPriority:(NSNumber *)x1 Value:(id)y1
and I've got two (strong) (synthesized) properties (x2,y2). If I do:
_x2=x1;
_y2=y1;
(which skips going through the property and just access the synthesized ivars) rather than
x2=x1;
y2=y1;
does ARC still function (like does it still keep a retain count thingy)?
You would set the instance variable directly, and not use the accessor. ARC will perform the reference counting.
Note: You will also want to preserve the semantics of your property in your initializer's implementation. For example, if it declared copy, you would then assign a copy of the parameter to the ivar in the initializer.
Additional Reading:
Should I refer to self.property in the init method with ARC?
Initializing a property, dot notation
ARC operates on assignment; otherwise it would be purposeless. (If it had to operate only through properties, it wouldn't add anything to what existed before ARC.) So yes, if you assign directly to the ivar, the assigned value is retained automatically.
And you should assign directly to the ivar if it is your ivar, because during init..., your object is not yet completely state-ready. So, in init..., perform any assignments to your ivars directly to the ivars; do not use the accessors / properties. Example:
- (id) initWithName: (NSString*) s {
self = [super init];
if (self) {
self->_name = [s copy]; //
}
return self; }
However, you can assign to your superclass's properties. So if this were a UIViewController subclass, assigning to self.title is fine.
For a complete explanation of how ARC works, see my book:
http://www.apeth.com/iOSBook/ch12.html
Yes, you can assign instance variables directly.
Without ARC, you would need to retain the object:
[_x1 release];
_x1 = [x1 retain];
With ARC, you can just assign the instance variable:
_x1 = x1;

Are getters the same for all properties in objective-c?

This simple question is bugging me. Are getters the same for
#property (nonatomic, retain) NSString *name
#property (nonatomic, copy) NSString *name
- (NSString*) name{
return name;
}
According to the documentation
A property declaration, however, provides additional information about
how the accessor methods are implemented (as described in “Property
Declaration Attributes”).
Both the getter and the setter behavior are defined by property declarations. In your example that is correct since it is defined nonatomic but if nonatomic were missing from the declaration it would would be implemented similar to this
- (NSString*) name{
[_internal lock]; // lock using an object-level lock
id result = [[name retain] autorelease];
[_internal unlock];
return result;
}
This of course is only true if you use #synthesize and do not override or change the getter and setter methods.
Yes, as the other answers state, the getters are the same. The options retain, copy, and assign determine how to generate setters, but not the names even of those.
If you want to use a different getter name, for instance if you have a BOOL such as the UIApplication property idleTimerDisabled, then you do this by specifically assigned the getter name:
#property(nonatomic, getter=isIdleTimerDisabled) BOOL idleTimerDisabled
Without an override such as this, the getter name is always the property name.
Yes, they are the same. retain, copy, and assign only give the compiler instructions on how to generate setters, not getters.
Yes, copy and retain only affect the setter and not the getter. On a side note, you should chose copy instead of retain for immutable objects like NSString.
If you're using ARC (Automated Reference Counting), then the getters should all look like what you have above. However, the new standard with ARC is to use strong and weak instead of retain and assign, respectively. retain and assign will still work and are synonymous with the strong and weak, but any newly generated files will use those words instead, so it's important to understand what they mean.
If you aren't using ARC (still an option, even in iOS 5 and Lion) getters can be different depending on retain, copy, or assign.
retain and copy both look like:
- (NSString *)name {
return [[name retain] autorelease];
}
assign is pretty basic, but is usually used more for weak references (like delegates):
- (id)delegate {
return delegate;
}
I went into some detail on this because it's important to understand when using ARC, the code for all 3 look the same, but the behavior is still very much like what's written above. If you're using atomic instead of nonatomic then you need to add some locking/unlocking lines to make the method thread-safe. In any case, it's generally better to use the default accessors generated with #synthesize unless you want to do something really tricky.
Yes, they are. The getter name dependce only of properties name.