When declaring the properties in Objective-C, what are the custom options available to configure, which define how the accessor methods would behave?
For example, you can have weak, strong, readonly.
Here's the short answer:
atomic vs nonatomic primarily ensures that complete values are returned from synthesized getters and that complete values are written by synthesized setters.
readwrite vs readonly determines whether a synthesized property has a synthesized accessor or not (readwrite has a setter and is the default, readonly does not).
assign vs weak vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme.
And now for the long answer:
Atomic v Nonatomic
Assuming that you are #synthesizing the method implementations, atomic vs. non-atomic changes the generated code. If you are writing your own setter/getters, atomic/nonatomic/retain/assign/copy are merely advisory.
With atomic, the synthesized setter/getter will ensure that a whole value is always returned from the getter or set by the setter, regardless of setter activity on any other thread. That is, if thread A is in the middle of the getter while thread B calls the setter, an actual viable value -- an autoreleased object, most likely -- will be returned to the caller in A.
In nonatomic, no such guarantees are made. Thus, nonatomic is considerably faster than atomic.
What atomic does not do is make any guarantees about thread safety. If thread A is calling the getter simultaneously with thread B and C calling the setter with different values, thread A may get any one of the three values returned -- the one prior to any setters being called or either of the values passed into the setters in B and C. Likewise, the object may end up with the value from B or C, no way to tell.
Ensuring data integrity -- one of the primary challenges of multi-threaded programming -- is achieved by other means.
Assign, weak, retain, copy
In a nutshell, assign vs weak vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme:
assign is the default and simply performs a variable assignment. It does not assert ownership, so the object pointed to by the property's pointer may disappear at any time if no others have asserted ownership themselves through retain or other means. In an ARC environment, assign does not ensure that pointers will not dangle, which means a pointer may end up pointing to junk if the object on the other side has been deallocated.
weak is identical to assign, except that it will zero out pointers that lead to deallocated objects to stop them from dangling. Weak is only available in an ARC environment.
retain specifies the new value should be sent -retain on assignment and the old value sent release. Retain is also know as strong.
copy specifies the new value should be sent -copy on assignment and the old value sent release. Copy is often used for properties in which the type of the property has a mutable cousin (NSArray/NSMutableArray) to prevent others from sending in mutable versions and altering them/having them altered behind their backs, and more.
Remember that retain/strong is done on the created object (it increases the reference count) whereas copy creates a new object. The difference, then, is whether you want to add another retain to the object or create an entirely new object.
Related
When they are being nil'd out because the last strong reference is gone, can you have a problem if that occurs on another thread? And if so, does using atomic correct for that? Since I believe Swift doesn't have atomics, what is required for a thread-safe weak property there?
weak is part of ARC, and is promised to be atomic by Clang in the way you're describing. See particularly section 4.2 Semantics in the Automatic Reference Counting documentation for Clang.
Of specific interest for this are these sections (emphasis added):
Reading
For __weak objects, the current pointee is retained and then released at the end of the current full-expression. This must execute atomically with respect to assignments and to the final release of the pointee.
Assignment
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.
Note that many other operations are not atomic, in particular strong assignments (for example, assigning a strong property on two different threads). But the retain counting itself is thread safe, which is really the piece you're worried about here. You are free to retain and release objects on any thread, and the retain count at the end will be correct, including "implicit" releases due to weak assignment. It's all the direct result of the following:
objc_retain is defined to be "exactly as if the object had been sent the retain message."
"Object allocation and retain count functions" are explicitly thread-safe.
The upshot of all of this is that, unlike most parts of Cocoa, reference counting is almost always going to be safely handled across threads.
Almost nothing in Swift is intrinsically thread safe — not references, not weak references, not arrays, not strings, nor any other mutable value.
If you want write/read or write/write access to anything from two threads, you must use locks to ensure safety.
https://medium.com/#mohit.bhalla/thread-safety-in-ios-swift-7b75df1d2ba6
This link should help!
I'm trying to learn/understand what happens and why when working with or creating various objects. (Hopefully to LEARN from the docs.)
I'm reading "Programming in Objective-C 2.0" (2nd edition, by Steven Kochan). On page 408, in the first paragraph is a discussion of retain counts:
Note that its reference count then goes to 2. The addObject: method does this automatically; if you check your documentation for the addObject: method, you will see this fact described there.
So I read the addObject: docs:
Inserts a given object at the end of the array.
There, the description is missing, while other items, like arrayByAddingObject:, state it:
Returns a new array that is a copy of the receiving array with a given object added to the end.
Where in the reference does it indicate that addObject: increases the retain count? Given the presence of ARC, I should still understand what these methods are doing to avoid bugs and issues. What does ARC bring to this? (Going to read that again...)
Great question, I'm glad to see someone actually reading the docs and trying to understand them!
Since you are looking for how to research answers using Apple's documentation more so than the actual answer itself, here is how I found the answer:
First I look at the class reference for addObject: which is a method of NSMutableArray and there is no mention of memory management.
Then I look at the Overview section at the top... Hmmm, still no luck.
Since the behavior might be inherited from a parent class, I look at the Inherits from section at the top of the class reference and see that NSArray is the most immediate parent. Let's check there:
Under the Overview There is one small section about retain's:
Special Considerations
In most cases your custom NSArray class should conform to Cocoa’s
object-ownership conventions. Thus you must send retain to each object
that you add to your collection and release to each object that you
remove from the collection. Of course, if the reason for subclassing
NSArray is to implement object-retention behavior different from the
norm (for example, a non-retaining array), then you can ignore this
requirement.
Okay, I'm still not happy... Where next? The parent class of NSArray is NSObject and I know that it won't be covered there in this case (from experience) so I won't bother checking that. (If the parent was another class or something that might be covered by NSObject, I would keep moving up the tree until I found something.)
The Companion Guides usually contains a lot of good information for these types of classes. Let's try the first one, Collections Programming Topics.
The first section (after Overview) is Accessing Indexes and Easily Enumerating Elements: Arrays. Sounds promising! Click on Relevant Chapters: “Arrays: Ordered Collections”
There it is under Array Fundamentals along with a link to even more information:
And when you add an object to an NSMutableArray object, the object
isn’t copied, (unless you pass YES as the argument to
initWithArray:copyItems:). Rather, an object is added directly to an
array. In a managed memory environment, an object receives a retain
message when it’s added; in a garbage collected environment, it is
strongly referenced. When an array is deallocated in a managed memory
environment, each element is sent a release message. For more
information on copying and memory management, see “Copying
Collections.”
The book must be referring to out of date documentation because you are correct it doesn't mention anything about the retain count. It does in fact retain the object though. The way you need to think of it is not in terms of retain counts (which are useless) but rather ownership. Especially so when using ARC.
When you add an object to an NSMutableArray, it is taking ownership of that object (in ARC terminology it has a strong reference to it).
"What does ARC bring to this?"
ARC does nothing different. All ARC does (besides some optimization) is add the same release, retain, and autorelease statements that you would add yourself without using ARC. All you need to care about is that once you add an object to the array, it will live at least as long as the array.
And the arrayByAddingObject: method creates a new NSArray (or NSMutableArray) containing the object you're passing, and keeps a strong reference to the passed object. The actual array object that it creates has no references yet unless you assign it to either an ivar, property, or local variable. What you assign it to determines it's lifespan.
Basically even without ARC, it's best to think of object life-cycles in terms of ownership, ARC just formalizes that. So because of that, when using the frameworks, it doesn't matter when retains happen or don't happen, you are only responsible for your objects until you pass ownership to another object and you can trust that the framework will keep the object alive as long as it needs it.
Now of course you have to intuit what constitutes ownership. For instance delegate properties are often assign, or in ARC unsafe_unretained or weak, to prevent circular retains cycles (where two objects each retain each other), though are sometimes retained/strong so you need to look into those on a case by case basis.
And also in cases like key value observing and NSNotification observing the object you are observing does not retain the observer.
But those are really exceptions to the rule. Generally you can assume a strong reference.
Regarding this sentence above: "The actual array object that it creates has no references yet unless you assign it to either an ivar, property, or local variable. What you assign it to determines it's lifespan." I'll try to explain:
When you run this piece of code: [someArray arrayByAddingObject:someObject]; you've instantiated a new NSArray or NSMutableArray object (depending on which object type someArray is) but you haven't actually assigned it to any reference. That means that if you're using ARC, it may be immediately released afterwards, or if not using ARC, it will be released when it's autoreleasepool is drained (probably on the next iteration of that thread's runloop).
Now if instead you did this: NSArray *someOtherArray = [someArray arrayByAddingObject:someObject]; you now have a reference to the newly created array, called someOtherArray. In this case, this is a local variable who's scope is only within whichever set of { } it resides (so it could be inside an if statement, a loop, or a method. Now if you do nothing else with it, it will die sometime after it's scope ends (it isn't guaranteed to die right away, but that isn't important, you just can't assume it lives longer).
Now if in your class you have an iVar (instance variable) declared in the header like NSArray *someOtherArray; (which is strong by default in ARC) and you run someOtherArray = [someArray arrayByAddingObject:someObject]; somewhere in your class, the object will live until you either remove the reference (someOtherArray = nil), you overwrite the reference (someOtherArray = someThirdArray), or the class is deallocated. If you were not using ARC, you would have to make sure to retain that to achieve the same effect (someOtherArray = [[someArray arrayByAddingObject:someObject] retain]; which is essentially what ARC is doing behind the scenes).
Or you may have a property declared instead like #property (nonatomic, strong) NSArray *someOtherArray in which self.someOtherArray = [someArray arrayByAddingObject:someObject]; would achieve the same effect but would use the proprety accessor (setSomeOtherArray:) or you could still use someOtherArray = [someArray arrayByAddingObject:someObject]; to set the iVar directly (assuming you #synthesized it).
Or assuming non-ARC, you might have declared the property like #property (nonatomic, retain) NSArray *someOtherArray in which self.someOtherArray = [someArray arrayByAddingObject:someObject]; would behave exactly as ARC would, but when setting the iVar directly you would still need to add that retain manually.
I hope that clears things up a bit, please let me know if there's anything I glossed over or left out.
As you mentioned in your comment, the key here is intuitively knowing when an object would be considered owned by another one or not. Luckily, the Cocoa frameworks follow a pretty strict set of conventions that allow you to make safe assumptions:
When setting an NSString property of a framework object (say the text property of a UILabel for example) it is always copied (if anyone knows of a counter-example, please comment or edit). So you don't have to worry about your string once you pass it. Strings are copied to prevent a mutable string from being changed after it's passed.
When setting any other property other than delegate, it's (almost?) always retained (or strong reference in ARC)
When setting delegate properties, it's (almost?) always an assign (or weak reference) to prevent circular retain cycles. (For instance, object a has a property b that is strong referenced and b has a strong referenced delegate property. You set a as the delegate for b. Now a and b are both strongly referencing each other, and neither object will ever reach a retain count of 0 and will never reach it's dealloc method to dealloc the other object. NSURLConnection is a counter-example that does strongly reference it's delegate, because it's delegate is set via a method -- see that convention below -- and it's convention to nil out or release an NSURLConnection after it completes rather than in dealloc, which will remove the circular retain)
When adding to an array or dictionary, it's always retained (or strong reference).
When calling a method and passing block(s), they are always copied to move them from the stack (where they are initially created for performance purposes) into the heap.
Methods that take in object parameters and don't return a result immediately are (always? I can't think of any that don't) either copying or retaining (strong referencing) the parameters that you pass to ensure that the method can do what it needs to with them. For instance, NSURLConnection even retains it's delegate because it's passed in via a method, whereas when setting the delegate property of other objects will not retain, as that is the convention.
It's suggested that you follow these same conventions in your own classes as well for consistency.
Also, don't forget that the headers of all classes are available to you, so you can easily see whether a property is retain or assign (or strong or weak). You can't check what methods do with their parameters, but there's no need because of the convention that parameters are owned by the receiver.
In general, you should look in the "most global" spot for information about anything in the Cocoa APIs. Since memory management is pervasive across the system APIs and the APIs are consistent in their implementation of the Cocoa memory management policy, you simply need to read and understand the Cocoa memory management guide.
Once understood, you can safely assume that all system APIs implement to that memory management policy unless explicitly documented otherwise.
Thus, for NSMutableArray's addObject: method, it would have to retain the object added to the array or else it would be in violation of that standard policy.
You'll see this throughout the documentation. This prevents every method's documentation from being a page or more long and it makes it obvious when the rare method or class implements something that is, for whatever reason (sometimes not so good), an exception to the rule.
In the "Basic Memory Management Rules" section of the memory management guide:
You can take ownership of an object using retain.
A received object is normally guaranteed to remain valid within the
method it was received in, and that method may also safely return the
object to its invoker. You use retain in two situations: (1) In the
implementation of an accessor method or an init method, to take
ownership of an object you want to store as a property value; and (2)
To prevent an object from being invalidated as a side-effect of some
other operation (as explained in “Avoid Causing Deallocation of
Objects You’re Using”).
(2) is the key; an NS{Mutable}Array must retain any added object(s) exactly because it needs to prevent the added object(s) from being invalidated due to some side-effect. To not do so would be divergent from the above rule and, thus, would be explicitly documented.
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".
Though the question is basic, but I found it very crucial to understand to proceed with IOS programming. Sometimes we used to declare only instance variable and we don't set any associated property to it. Some where we just declare the properties and use synthesize to get or set the values. Sometimes I feel necessary to declare both in code, when compilation gives me warnings! What's the fundamental behind the manipulation of properties in Objective C. I know the basic requirement to create getter and setter for any instance variable, but when?
I have seen it many times we don't use property at all, and after that too we easily set and get variable's value. Also, different types of property like atomic, non atomic, strong, retain are very unclear to me. XCODE up-gradation to 4.2 has shaken my concepts about memory management. Can somebody please clear the cloud over my mind?
Properties are always the preferred way over direct ivar access, mostly of following reasons:
You can override a getter or setter in a subclass
You can define the "assigning behavior" (namely copy, assign, retain/strong, weak)
You can synchronize ivar access
Keywords:
copy: The object is copied to the ivar when set
assign: The object's pointer is assigned to the ivar when set
retain/strong: The object is retained on set
weak: In ARC this is like assign, but will be set to nil automatically when the instance is deallocated, also used in a garbage collected environment.
nonatomic: The accessor is not #synchronized (threadsafe), and therefore faster
atomic: The accessor is #synchronized (threadsafe), and therefore slower
Generally you should always synthesize an ivar. If you need faster access for performance reasons you can always access the synthesized ivar directly too.
While typing I saw that 'Erik Aigner' was faster with a good answer.
For een example on properties, synthesize and custom setter see my answer on stack:
Objective-C convention to prevent "local declaration hides instance variable" warning
For an stater tutorial on ARC see the explenation on Ray wenderlich his website:
Beginning ARC in iOS 5 part 1 and
Beginning ARC in iOS 5 part 2
I have member variables in my custom UIViewController that are defined as 'assign' (not 'retain') like this:
#property (nonatomic, assign) UIButton* mSkipButton;
In my loadView method, I set the var, for instance self.mSkipButton, to an autoreleased alloc of the variable type. I then attach it to my controller's view essentially having the view reference count and release it as needed.
This concerns me, however, that I have the pointer stored in my member var and that it could be referencing released memory if the count decrements at some point. Is it better practice to instead declare the variable as 'retain' and then in the viewDidUnload method release the member var (or just set it to nil to release and make sure i don't have an address in there)?
Alternatively, could I simply set the member var to nil in viewDidUnload and not make it a retained variable?
Is it better practice to instead declare the variable as 'retain' and then in the viewDidUnload...?
Yes, use retain -- good instinct. In viewDidUnload, you'd typically just set it to nil via the ivar's setter: self.ivar = nil;
I find it easier to be aware of and manage object codependencies explicitly, than to deal with issues related to using assign. You can completely avoid the issues of holding an unmanaged reference.
Arguments can be made that assign would usually be fine here (and it is in some cases), but using assign can complicate object graphs and ownership for anyone working with the class. As program complexity grows (and the libraries you depend on change), it becomes increasingly difficult to track lifetimes of unmanaged references. Things tend to break, or operate differently on different hardware and software combinations. Attempting to manage the lifetime of an unmanaged object over a complex program or in a concurrent context is self abuse. Guaranteeing defined and predictable behavior/operation reduces bug counts.
That's a property, not a "member var" (known in Objective-C as an instance variable or ivar.)
The semantics of a property depend on how that property is going to be used. Generally speaking, you'll want your properties to be retained for the lifetime of your object. If the property is a connected IBOutlet, this will be done for you by the NIB loader; otherwise, you must be explicit and use the retain or copy attribute on the property.
For objects that are expected to own your object, a property should always be marked assign to avoid a retain loop. For example, an object usually owns any object for which it acts as a delegate (usually, but not always--every CS rule has an exception.)