Should an NSString property under ARC be strong or copy? - objective-c

When not compiling with ARC, it is recommended to use copy properties for data types such as NSString. I could not find proper documentation on the use of copy in ARC mode. Can someone tell me what's applicable for ARC?

It is still recommended to copy because you want to avoid something passing a mutable string and then changing it without you knowing. A copy guarantees that the string you have will not change.

Copying and ARC are orthogonal: you make copies of mutable objects to "freeze" their state; ARC keeps track of object's reference count.
NSString objects may or may not be mutable. When you receive an NSString* as a parameter, you cannot be certain that it is immutable unless you check its type (and even then you may get false positives). If your algorithm relies on the string not changing after being set, making a copy is the right thing to do. ARC, on the other hand, will ensure that the object is not released while you are holding a strong reference to it.

It doesn't matter if you're using ARC or non-ARC.
The reasoning behind the copy is so that you can guarantee that your class' internal state can't be modified from outside the implementation.
This could happen if someone passes you an NSMutableString, and then modifies it later. That consideration is independent of the memory management environment.

copy counts as strong. Use:
#property(nonatomic,copy) NSString *name;
https://devforums.apple.com/message/654033#654033
or even:
#property NSString *firstName;
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses.html#//apple_ref/doc/uid/TP40011210-CH3-SW7

Related

Cocoa atomic properties and autorelease

If I have an an atomic property in MyClass:
#property (readwrite, strong) NSMutableArray *atomicArray;
And a thread calls something like:
NSMutableArray* t = [myClassObject atomicArray];
Where is it documented that the object I get back is retained/autoreleased so that another thread can't call:
[myClassObject setAtomicArray:otherArray] and eliminate the object out from under me?
Another question mentioned this is true but without reference to any documentation from Apple.
Atomic properties vs thread-safe in Objective-C
See The Objective-C Programming Language, Property Declaration Attributes, Atomicity:
If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:
[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
If you specify nonatomic, a synthesized accessor for an object property simply returns the value directly.
Assuming you are using ARC, the reference obtained in t is a strong one to the object that existed at the time you retrieved it. If some other thread replaces the object, t would still reference the original object, and that object would stick around until t goes out of scope.
However t being a mutable array, some other thread could get its own reference and modify the mutable array itself by adding and removing objects. Those changes would be visible to your t, because it is the same object.
That is important, because if you try to iterate over the array while some other thread modifies it, you may encounter all kinds of unexpected results. Depending on your Xcode version it might produces warnings during compile and/or runtime to help identify those scenarios. One pattern to avoid the array changing from under you is to create an immutable copy, like NSArray *immutableT=[t copy]. This produces a shallow copy of the array that is immune to changes to the original mutable array, so you can safely iterate over immutableT.
This is a helpful hint, but can you try using Memory Graph Debugger feature of Xcode. Working on strong attributes with multi-threading is always a tedious task.
Memory graph debugger is an excellent tool to find out retain count, who is holding a strong reference of an object, etc.. It helps a lot if you play around with it.

Objective-c copy a strong property [duplicate]

When not compiling with ARC, it is recommended to use copy properties for data types such as NSString. I could not find proper documentation on the use of copy in ARC mode. Can someone tell me what's applicable for ARC?
It is still recommended to copy because you want to avoid something passing a mutable string and then changing it without you knowing. A copy guarantees that the string you have will not change.
Copying and ARC are orthogonal: you make copies of mutable objects to "freeze" their state; ARC keeps track of object's reference count.
NSString objects may or may not be mutable. When you receive an NSString* as a parameter, you cannot be certain that it is immutable unless you check its type (and even then you may get false positives). If your algorithm relies on the string not changing after being set, making a copy is the right thing to do. ARC, on the other hand, will ensure that the object is not released while you are holding a strong reference to it.
It doesn't matter if you're using ARC or non-ARC.
The reasoning behind the copy is so that you can guarantee that your class' internal state can't be modified from outside the implementation.
This could happen if someone passes you an NSMutableString, and then modifies it later. That consideration is independent of the memory management environment.
copy counts as strong. Use:
#property(nonatomic,copy) NSString *name;
https://devforums.apple.com/message/654033#654033
or even:
#property NSString *firstName;
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses.html#//apple_ref/doc/uid/TP40011210-CH3-SW7

If you bridge a CFArrayRef of CFStringRefs to NSArray, can you treat the contents as NSStrings?

Suppose I have a CFArrayRef containing CFStringRefs inside it and I bridge it over to NSArray using CFBridgingRelease(). Can I now treat the contents of the array as regular NSString instances and call all of the usual NSString methods?
If so, does this mean toll-free bridging happens recursively throughout the object when it's bridged? E.g. if I had a CFArray of CFArrays of CFDictionaries or something, they'd all be transparently converted to NSArray, NSDictionary, etc?
Toll free bridging does not involve any conversion (or there would be a cost), so talking about doing it recursively does not make sense.
What toll free bridging does in your case is determine who is responsible for managing the lifetime of the object - the programmer for the CF array, ARC for the NS array.
Further whether an object internally uses manual memory management or ARC is not important to the user of that object - they can use either style.
Combine the above and you have your answer: once you've handed your CF array of strings over to ARC your job is done.
HTH
CRD's answer is good and I've given it a +1. Here's a bit more explanation:
First, type-casting is a purely compile-time thing. And it doesn't cost anything. It just tells the compiler not to complain.
Toll-free casting of Core Foundation types to Cocoa types is because those objects are, under the hood, the same thing. The cast is just necessary to inform the compiler of that fact. Such a cast doesn't "do" anything. For example, in non-ARC code:
CFStringRef cfstring = /* ... */;
NSString* nsstring = (NSString*)cfstring;
That assignment is still just an assignment. The pointer value from cfstring is still just copied verbatim into the storage of nsstring. Nothing else happens.
Depending on how you obtained the CFString that cfstring was pointing to, you may have had a responsibility to release it. Since this is non-ARC, you still have that responsibility after it has been assigned to nsstring, which you can discharge either by calling CFRelease(cfstring) or [nsstring release] or [nsstring autorelease] when you're done with it. Once you do that, the value in both variables must be considered unusable as dangling pointers.
The case with ARC is only slightly different. An ARC bridging cast is also a compile-time thing, but it affects what code the compiler emits for automatic memory management. Since it has emitted different code, that technically has implications for run-time, but they are not related to the type-cast as such. The bridging cast tells the compiler whether it should emit retains or releases (or neither) of the object which is the subject of the expression. That's all; just a question of retaining or releasing the object. So, it has no effect on, say, objects within an array because those objects are not the subject of the expression, the array is. And it doesn't even do anything to the array beyond potentially retaining or releasing it.
Let me try and take a simpler approach to an answer:
A CFArrayRef can be treated as an NSArray* and vice versa.
A CFStringRef can be treated as an NSString* and vice versa.
Thus, an CFArray of CFStrings is an NSArray of NSStrings. You just need to cast it. (In so doing with __bridge_*, you also transfer the memory management to ARC.)

Objective-C Mutable property, copy retain, etc?

When I declare a property for an interface that is Mutable should I always make it (nonatomic, copy)? Also when would I used assign instead of retain?
Use nonatomic when you care more about performance than thread safety. Atomic properties are thread safe but slower. The default behaviour is atomic.
Use copy when you want a copy to be made whenever a new value is set to the property. Note that in many cases, copy will not actually make a copy of the object, so this usually has no performance impact but can solve bugs if somebody gives you a mutable copy (eg, you have an NSString property and somebody assigns an NSMutableString.
Do not ever use retain or strong as these are only needed when ARC is turned off, and you should always have ARC turned on. strong and retain are the same, and this is the default behaviour with ARC enabled. Just turn ARC on and ignore these ones, except for backwards compatible code.
Sometimes, for example delegate properties, using retain or strong would create a memory leak. In these situtaions you need to use weak or assign. In general, you should use weak, as assign can have rare edge case bugs.
Normally you #synthesize a property in your class implementation which creates a set function. You can write your own property set function, and do a mutable copy there. Problem solved...
- (void)setPropertyName:(propertyType *)newProperty {
if (propertyName) [propertyName release];
propertyName = [newProperty mutableCopy];
}

Objective-C declared #property attributes (nonatomic, copy, strong, weak)

Can someone explain to me in detail when I must use each attribute: nonatomic, copy, strong, weak, and so on, for a declared property, and explain what each does? Some sort of example would be great also. I am using ARC.
Nonatomic
Nonatomic will not generate threadsafe routines thru #synthesize accessors. atomic will generate threadsafe accessors so atomic variables are threadsafe (can be accessed from multiple threads without botching of data)
Copy
copy is required when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
Assign
Assign is somewhat the opposite to copy. When calling the getter of an assign property, it returns a reference to the actual data. Typically you use this attribute when you have a property of primitive type (float, int, BOOL...)
Retain
retain is required when the attribute is a pointer to a reference counted object that was allocated on the heap. Allocation should look something like:
NSObject* obj = [[NSObject alloc] init]; // ref counted var
The setter generated by #synthesize will add a reference count to the object when it is copied so the underlying object is not autodestroyed if the original copy goes out of scope.
You will need to release the object when you are finished with it. #propertys using retain will increase the reference count and occupy memory in the autorelease pool.
Strong
strong is a replacement for the retain attribute, as part of Objective-C Automated Reference Counting (ARC). In non-ARC code it's just a synonym for retain.
This is a good website to learn about strong and weak for iOS 5.
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
Weak
weak is similar to strong except that it won't increase the reference count by 1. It does not become an owner of that object but just holds a reference to it. If the object's reference count drops to 0, even though you may still be pointing to it here, it will be deallocated from memory.
The above link contain both Good information regarding Weak and Strong.
nonatomic property means #synthesized methods are not going to be generated threadsafe -- but this is much faster than the atomic property since extra checks are eliminated.
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.
weak ownership means that you don't own it and it just keeps track of the object till the object it was assigned to stays , as soon as the second object is released it loses is value. For eg. obj.a=objectB; is used and a has weak property , than its value will only be valid till objectB remains in memory.
copy property is very well explained here
strong,weak,retain,copy,assign are mutually exclusive so you can't use them on one single object... read the "Declared Properties " section
hoping this helps you out a bit...
This link has the break down
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.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.
Great answers!
One thing that I would like to clarify deeper is nonatomic/atomic.
The user should understand that this property - "atomicity" spreads only on the attribute's reference and not on it's contents.
I.e. atomic will guarantee the user atomicity for reading/setting the pointer and only the pointer to the attribute.
For example:
#interface MyClass: NSObject
#property (atomic, strong) NSDictionary *dict;
...
In this case it is guaranteed that the pointer to the dict will be read/set in the atomic manner by different threads.
BUT the dict itself (the dictionary dict pointing to) is still thread unsafe, i.e. all read/add operations to the dictionary are still thread unsafe.
If you need thread safe collection you either have bad architecture (more often) OR real requirement (more rare).
If it is "real requirement" - you should either find good&tested thread safe collection component OR be prepared for trials and tribulations writing your own one.
It latter case look at "lock-free", "wait-free" paradigms. Looks like rocket-science at a first glance, but could help you achieving fantastic performance in comparison to "usual locking".