iOS copy properties creation of new objects, retain, memory allocation - ios

If I have a copy property and set it to another object, I actually create a new object with a retain count of 1.
#property (copy) myObject;
myobject = someOtherObject;
//&myOBject != &someOtherObject
At this point, let's call address of myObject &myObject1.
If I go and do this after I set myObject to someOtherObject
myObject = someOtherObject2
what happens to &myObject1? Now myObject point to a value that is equivalent to someOtherObject2's value but at a new memory address. What happens to the &myObject1 and is there anything still pointing to it?

Note that the #property statement in the question does not have a type supplied.
If someOtherObject is immutable a copy is not made, only the reference count in incremented and both myobject and someOtherObject point to the same object. That os all that is needed since an immutable object can not be changed. A change to either pointer will change the single object.
If someOtherObject is mutable a copy is made and there are now two distinct instances. No change is made to the original someOtherObject. Both my object and someOtherObject point to separate instances and have no relation to each other. If they are mutable a change to one will not change the other.

Related

What does retain as property attribute exactly do in objective-c?

If I declare a public property as :
#property (retain) NSString * name;
Then how does the compiler implicitly implement this? I have read that the retain gains ownership over the instance variable "_name". I have also read that "retain" message increases the reference count of the object.
So each time I call the setter for "name" property in the above example, will it increase the reference count?
So after this,
object.name=#"name1";
object.name=#"name2";
Will the reference count be 2?
To answer your specific question:
object.name = #"name1";
name now holds a strong reference to the "name1" string instance.
object.name = #"name2";
name now holds a strong reference to the "name2" string instance. No object holds a reference to the "name1" instance, and a release statement will be inserted by the compiler for "name1". (in practice, the first statement will likely be optimized away entirely).
According to Blamdarot in this answer:
"retain" is needed when the attribute is a pointer to an object. The setter generated by #synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.

How to get the address of an object in an NSMutableArray

How can I get the Address of an object stored in a NSMutableArray?
I have something like this:
class member variable in .h:
MyClass *__strong*_selectedobject;
in a function in .m:
MyClass *objReference = [_messageBoards objectAtIndex:idxInCaseOfContract];
_selectedobject = &objReference;
the problem is, that _selectedobjectis nil as soon as the function finishes.
_selectedobject is an instance variable within a singleton class. It works with other objects which are not within an array. Also, the object within the array is not suddenly nil, it is just the reference.
You can not get pointer to a position inside an array in Objective-C.
If you need to retain position in an array, so that if another object is written there you'll have it instead of the old one, then save index of that position (and retain the array too if needed). Mind that modifications to the array may render the index invalid.
If you need to retain only the object which was read from array at that moment, simply retain that object. Object address is the object pointer itself, there are no extra indirections.
UPDATE
I'm just posting here how you can store reference to address in object(as question was originally about that), however I strongly advice anyone to think again if this is actually needed:
#interface MyClass : NSObject
{
NSMutableArray* test;
__strong id* foo;
}
*foo = [test objectAtIndex:2];
ORIGINAL ANSWER
As #Vijay-Apple-Dev.blogspot pointed out you are missing something very important about memory - you are making _selectedobject to point to address of temporary variable(objReference) instead of object in memory([_messageBoards objectAtIndex:idxInCaseOfContract]). All method variables becomes nil after their method goes out of scope, and thats why your reference becomes nil(although array is still alive and object is there). Simply do not use local variable and everything should be fine.
Side note - what's the purpose of using address reference instead of object pointer? If you think you're gone save memory you are wrong, as ARC(and MRC also) are working differently ;)
MyClass *objReference is local variable to the method. So once it method finishes, everything will be gone from memory. If you want to keep them, then you have retain them in header file(.h) as instance variable.
#property(nonatomic,retain) MyClass *objReference;
then
self.objReference = [_messageBoards objectAtIndex:idxInCaseOfContract];
NOTE: You must use the self dot syntax when u retain the object. otherwise wont work.

Whether I should use #property(nonatomic,copy) or #property(nonatomic,strong) for my (NSString *) attr in An object?

#interface PaneBean : NSObject
#property(nonatomic,copy) NSString *name;
#property(nonatomic,copy) NSString *type;
#property(nonatomic,assign) NSInteger width;
#end
I have a PaneBean as is shown above.
Whether I should use #property(nonatomic,copy) or #property(nonatomic,strong) for my (NSString *) name? What is the difference between them?
And is it right to write 'assign' for NSInteger?
Any help appreciated.Thanks in advance!
'copy' will cause the setter for that property to create a copy of the object, and is otherwise identical to strong. You would use this to make sure that if someone sets your property to a mutable string, then mutates the string, you still have the original value. If the string isn't mutable, Cocoa will silently optimize out the copy operation, which is nice :)
'strong' will keep the property's value alive until it's set to something else. If you want incoming mutable strings to change out from under you (not impossible, but not all that common, a thing to want), then strong would be the right thing to do. Generally strong is more useful for objects that represent something more complex than a simple "value" (i.e. not NSString, NSNumber, NSValue, etc...).
'assign' is the default (and indeed only) possible setting for an integer. Integers can't be retained or copied like objects.
For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your #property declaration. Specifying retain is something you almost never want in such a situation.In non ARC strong will work like retain
Here's why you want to do that:
NSMutableString *someName = [NSMutableString stringWithString:#"Chris"];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
[someName setString:#"Debajit"];
The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be #"Debajit" if the property is marked retain, but #"Chris" if the property is marked copy.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using #synthesize you should remember to actually use copy instead of retain in it.)
copy sends the copy message the object you set, while strong only retains it (increments the reference count).
For NSString , or in general any inmutable class with known mutable subclasses(NSArray, NSDictionaty, NSSet), copy is preffered to avoid clients setting a mutable instance and modifying it out of the object.
For primitive types(int for example) copy/strong does not make sense and by default assign is used. Is up to you if you want to put it explicitly or not.
Strong indicates composition, while Weak indicates aggregation.
Copy means that a new object is to be created before the contents of the old object are copied into the new object. The owning object, PaneBean in this case, will be composed of the newly created object.

iOS: Copy property

I couldn't get the right answer for this question. If it is found duplicate, please make it duplicate with the right reference link.
I wanted to know, what are the ways the reference count is incremented. I know, alloc/init and retain increases the reference count, does 'copy' also increases the reference count to '1' ?
Thanks.
copy creates a new object which is, as the method name suggest, a carbon copy of the receiver (well in fact it depends of the implementation of the copy method in each class, but that's the aim of the method anyway).
So in fact it does not really "increase the reference count of the by 1" but it rather create a new object, with a refcount of 1 as any newly allocated object, and make it have the same property / ivar values as the original.
So imagine you have a Person class with the properties name, surname and age, if you needed to implement the copy method yourself it would look sthg like this:
-(id)copy
{
// Create a new instance
Person* mycopy = [[Person alloc] init];
// Make it an exact copy of the original
mycopy.name = self.name;
mycopy.surname = self.surname;
mycopy.age = self.age;
// and return that copy
return mycopy;
}
Note that in this case, if you modify the copy later, the original is not modified, because it is a different instance.
With this principle, the original object does not have its refcount incremented by one, but you have a new object whose refcount is one (as if you just did alloc/init to create this new object yourself) and you still have to release or autorelease it at some point yourself (if you are not using ARC). That's why calling copy on an object obey the same rules as retain or alloc regarding the need to call release or autorelease to balance the refcount at some point
Note that there is some exceptions / special cases, especially for some classes that are known as "immutable", like NSArray or NSString. In such cases, it is reasonable to thingk that making a copy (aka a different object instance) that is a clone of the original, whereas the original cannot be modified, is not really efficient, and can be optimized.
So in cases like NSArray and NSString and some other, the copy method may simply implemented to do a simple retain as the behavior will be the same as you can't modify the original (and neither the copy) because these are immutable classes by nature.
Of course, the implementation of mutableCopy (to get an NSMutableArray from an NSArray for example) do a real copy and not a simple retain, and the implementation of the copy method in the mutable subclasses like NSMutableString and NSMutableArray do a real copy too, but for the case that request an immutable copy of an immutable object, the point of allocating a different instance is generally useless and memory-consuming and is thus implemented the same as a retain.
But all this probable optimization does not change neither the behavior (because the classes are immutable) nor the memory management policy (as you still need to release the object returned by copy)

iOS: Setting properties

When I'm setting a property with an object that is currently in a retained NSArray, will it only store the pointer (light-weight), or will it copy the contents to the property?
From what I know, it seems like it would only assign the pointer, but I'm not sure.
Also, under what circumstances would using *pointer = *otherPointer or the set methods (setDelegate, for instance) copy the value, instead of just passing the pointer, if any.
Shouldn't it always just pass the pointer address?
It always passes the pointer, as you said. Unless you are specifically adding a de-referencing sign, this will always be the case.
However, when you add a property to a class, and set the setter to copy:
#property (nonatomic, copy) id obj;
When using the dot syntax or the setter, This will be translated to:
_obj = [otherObj copy];
Here, it will depend whether the object in question supports copying itself, or will it fall back to it's super class NSObject or another intermediate class's copy.
Moreover, Collection classes NSDictionary and NSArray do a shallow copy, as in they copy the references to their objects only, so you have two collections pointing to the same set of objects.

Resources