Basic Objective-C memory management syntax - objective-c

I have a property defined like this:
#property (nonatomic, retain) MyClass *someObject;
I'm currently using this assignment statement:
someObject = [[MyClass alloc] init];
In terms of memory managment is the above assignment statement equivalent to:
self.someObject = [[[MyClass alloc] init] autorelease];
Assume #synthesize someObject; is in the #implementation section. Also I'm not using ARC.

Note: The following is based on the EDITED version of the original post, where "assign" has been replaced with "retain" ---
Yes, the two are "equivalent", in that they will both result in leaving the MyClass object (properly) retained with a retain count of 1 in the property. The second version goes through some extra work, which may or may not be an issue, depending on how performance-sensitive you are.
Some people argue you should never use the property reference (ie, self.propname) from within the class, but instead reference the instance variable, especially for initialization and deallocation. Others argue just the opposite. I generally favor always using the property reference, except during initialization where (as in this case) using it might result in an extraneous retain/autorelease.

Related

Setting WEAK to a non #property variable

Will need someone with knowledge of ARC to help me.
Basically, I have declared some variables as such in my class
#interface Class{
NSString* one;
NSString* two;
}
#property(nonatomic,weak) NSString* one;
As you can see, I can set the weak identifier to NSString* one. However, I do not need a getter/setter/synthesizer for NSString* two as it is just a common variable. How can I set a weak label to it so the memory is deallocated? Or is automatically set?
You can do it like this:
__weak NSString *two;
But you probably do not want to do it in this case.
Declaring an instance variable __weak means that the reference to the target object (a string in your case) will exist only as long as some other object holds a reference. When the last object holding a strong reference releases the string, your variable two will get nil-ed out automatically. This is very useful when objects hold references to each other, such as in parent-child hierarchies. Since your NSString *two could not possibly hold a reference to your object, using the __weak reference for it is highly questionable.
You can do this without worrying:
NSString* two = [[NSString alloc] init];
When your instance of the class Class is release for some reason, since is the only one (in theory) referencing two, it will be deallocated.
My advice (and I think Apple's although I could be wrong) would be to get into the habit of always using properties for your iVars, then this problem goes away.

copy property and Block_copy(myBlock) / [myBlock copy]

Consider:
typedef void (^select_block_t)(UIView *) ;
(1) #property (copy, nonatomic) select_block_t myBlockProperty ;
(2) #property (strong, nonatomic) select_block_t myBlockProperty ;
(3) #property (assign, nonatomic) select_block_t myBlockProperty ;
and:
(A) self.myBlockProperty = ^(UIView *) {NSLog(#"Hi");} ;
(B) self.myBlockProperty = [^(UIView *) {NSLog(#"Hi");} copy] ;
I am trying to understand what is the correct way to map which property declaration with which block copy semantics
I have seen examples here on S.O. that would favor[1:B]
But then I get confused by how redundant the 'copy' operation is.
My limited understanding is that [1:A] should be correct, because I want
the block to be copied once when I assign the property, not once at block creation and then once again at property assignment time.
[3:B] would also make sense according to my rationale. So, what am I misunderstanding?
[1:A] is correct, yes. [3:B] is incorrect because:
it's not clear that the class owns the property, so should release it in dealloc (but it should)
the setter (B) looks like a leak, and the static analyser might flag it as such, because the block is copied, handed to a property, then leaves the scope with retain count +1.
using (3) means that it only works if you set a heap-block (a copied block) with a retain count of one. This leaves plenty of margin for error when using the property. (1) works with both stack-blocks and heap-blocks, and will also correctly retain auto-released blocks.
EDIT: I see you're using ARC. In that case, it's not possible to use [3:B] at all. The compiler will release an object (even when copyed) once it's out of scope, and this property setter won't have retained it. Therefore the property will contain a bad pointer, it's an EXC_BAD_ACCESS waiting to happen.

#property definitions with ARC: strong or retain?

Using Xcode 4.2 and ARC, I notice that the auto-generated code for an NSManagedObject still reads like this for properties:
#property (nonatomic, retain) NSString * someString;
1) Shouldn't retain now be replace with strong or weak?
2) Why does the auto-generated code still use retain
3) What is the correct replacement for retain in this property statement?
I'm currently debugging a problem using NSFetchRequest, and I thought this might be the source of the problem. Thoughts?
1) Shouldn't retain now be replace with strong or weak?
No. You cannot replace retain with weak; they are different. And strong is a 100% synonym for retain; they are identical. You can use either, so there is no "should" here. You can replace retain with strong if you like, but you don't have to.
2) Why does the auto-generated code still use retain
Why not? See (1). retain is correct so there is no problem.
3) What is the correct replacement for retain in this property statement?
There is no need to replace retain.
I'm currently debugging a problem using NSFetchRequest, and I thought this might be the source of the problem. Thoughts?
It isn't.
To answer all three questions in one: retain and strong are synonymous with each other, so both are correct. The documentation states
retain implies __strong ownership
strong implies __strong ownership
Before ARC, you have to 'release' an object which is retained. That mean retain has counter part. After ARC you don't need to release. So use strong. Its a visual clue that you don't need to call release.
"retain" is equals to "strong".
"strong" is used for example:
#property (nonatomic, strong) NSString * someString;
And "__strong" is used for example:
-(void) someMethod
{
__strong NSString* vStr = [[NSString alloc] initWithString:#"some string"];
}
On Apple Docs. says:
Property Attributes
The keywords weak and strong are introduced as new declared property attributes, as shown in the following examples.
// The following declaration is a synonym for: #property(retain) MyClass *myObject;
property(strong) MyClass *myObject;
Apple doc. http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Objective-c object releasing patterns

I've run into some unfamiliar Objective-c memory management code. What is the difference between:
// no property declared for myMemberVariable in interface
id oldID = myMemberVariable;
myMemberVariable = [MyMemberVariable alloc] init];
[oldID release];
and:
// (nonatomic, retain) property is declared for myMemberVariable in interface
self.myMemberVariable = [[MyMemberVariable alloc] init];
Thanks!
The second is technically incorrect, but the first probably stems from someone yet to embrace Objective-C 2.0 property syntax. It was added relatively recently if you're a long-time OS X developer (or an even-longer-time NextStep/OS X developer), so you do see people not using it without gaining any benefit or detriment by not doing so.
So the first is basically the same as:
[myMemberVariable release];
myMemberVariable = [[MyMemberVariable alloc] init];
Given that you have a 'retain' property, the correct version with the setter should be:
// this'll be retained by the setter, so we don't want to own what we pass in
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease];
In the first example, you've got an instance variable. In the second, a property with auto memory management attributes (as indicated by the retain).
In the first example, you're allocating an object, assigning it to an instance variable, then releasing it. It also appears that you're also leaking the object that was previously assigned to it since you don't explicitly release it. (Maybe it's autoreleased, can't tell here).
In the second example, you're allocating an object, and assigning it to a property that is retaining it. This means you're going to leak it unless you explicitly release/autorelease it.
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease];
or
MyMemberVariable *m = [[MyMemberVariable alloc] init];
self.myMemberVariable = m;
[m release];
It's much better to use properties as you get (most) memory management for free. For example, you won't have to worry about freeing a reference before assigning a new one.
The first form does not use properties. I don't see a good reason not to do:
[myMemberVariable release];
myMemberVariable = [[MyClass alloc] init];
Since the old value is definitely not the same as the new one, so there is no chance any old value is released before it can be retained again.
Properties have the advantage that, in newer compilers, they are synthesized by the compiler and simply do the right thing, i.e. they know how to retain the new and release the old value, if the type is one that must be retained or copied. This is not necessary for types like int, float, etc., since these are simple value types.
In other words, if you use dot notation, either on self or on some other object, you access the property and in fact call either the getter or setter methods, depending on the direction of assignment.
If you access the ivar (member variable) directly, you don't have the protection from the property and have to code retain/release yourself.
You can also write your own setters and getters, and then you'll also have to take care of memory management, where it applies. It does, however, give you more flexibility. You could log items, check the validity of the input, update internal state variables, etc.

Object allocate and init in Objective C

What is the difference between the following 2 ways to allocate and init an object?
AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];
and
self.aController= [[AController alloc] init];
Most of the apple example use the first method. Why would you allocate, init and object and then release immediately?
Every object has a reference count. When it goes to 0, the object is deallocated.
Assuming the property was declared as #property (retain):
Your first example, line by line:
The object is created by alloc, it has a reference count of 1.
The object is handed over to self's setAController: method, which sends it a retain message (because the method doesn't know where the object is coming from), incrementing its reference count to 2.
The calling code no longer needs the object itself, so it calls release, decrementing the reference count to 1.
Your second example basically does steps 1 and 2 but not 3, so at the end the object's reference count is 2.
The rule is that if you create an object, you are responsible for releasing it when you're done with it. In your example, the code is done with tempAController after it sets the property. It is the setter method's responsibility to call retain if it needs that object to stick around.
It's important to remember that self.property = foo; in Objective-C is really just shorthand for [self setProperty:foo]; and that the setProperty: method is going to be retaining or copying objects as needed.
If the property was declared #property (copy), then the object would have been copied instead of retained. In the first example, the original object would be released right away; in the second example, the original object's reference count would be 1 even though it should be 0. So you would still want to write your code the same way.
If the property was declared #property (assign), then self isn't claiming ownership of the object, and somebody else needs to retain it. In this case, the first example would be incorrect. These sorts of properties are rare, usually only used for object delegates.
As others have noted, the two code snippets you show are not equivalent (for memory management reasons).
As to why the former is chosen over the latter:
The correct formulation of the latter would be
self.aController= [[[AController alloc] init] autorelease];
Compared with the former, this adds additional overhead through use of the autorelease pool, and in some circumstances will lead to the lifetime of the object being unnecessarily extended (until the autorelease pool is released) which will increase your application's memory footprint.
The other "possible" implementation (depending on where the example is from) is simply:
aController = [[AController alloc] init];
However, setting an instance variable directly is strongly discouraged anywhere other than in an init or dealloc method. Elsewhere you should always use accessor methods.
This brings us then to the implementation shown in sample code:
AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];
This follows best practice since:
It avoids autorelease;
It makes the memory management semantics immediately clear;
It uses an accessor method to set the instance variable.
Note also that your desire to cut the code down to one line is why many people use Autorelease:
self.aController = [[[AController alloc] init] autorelease];
Though in theory on the iPhone autorelease is somehow more expensive (never heard a clear explanation why) and thus you may want to explicitly release right after you assign the object elsewhere.
If you're using Xcode, it can help you detect such code with the static analyzer.
Just hit Build >> Build and Analyze
This will show you a very helpful message at such pieces of code.
One other thing to note is that your example depends on the #property definition of aController also.
If it were defined as #property (readwrite, retain) id aController; then your example works, while if it is defined as #property (readwrite, assign) id aController; then the extra call to release would cause your object to be deallocated.
You could also do
#property (nonatomic, retain)AController *aController;
...
self.aController= [[AController alloc] init];
[aController release];
with a retaining property, and it would function the same way, but its better to use the other way (for retaining properties) because it's less confusing, that code makes it look like you assign aController and then it gets deleted from memory, when actually it doesn't because setAController retains it.