Assigning retaining object to weak property; object will be released after assignment - objective-c

I wrote on Xcode6 the example of Objective-C delegation pattern on Wikipedia. Every time you set the delegate there is a Warning "Assigning retaining object to weak property; object will be released after assignment". After running the example, methods f and g of A class dont execute.
Changing the line
#property (weak, nonatomic) id i; // delegation
to
#property (strong, nonatomic) id i; // delegation
fix the problem. Why is that?

Generally, in the delegate pattern you want the reference to be weak, because it refers to a delegate which is the strong property of another object. Since these are generally not owned by the object that has the delegate property (i in your example), you don't want to keep a strong reference to them. In fact, it is quite common that you would have an object, such as a window controller (or navigation controller in iOS) that owns an object (such as a control of some kind) whose delegate you want to set back to the window controller (or navigation controller).
In this case, you need the delegate reference to be weak in order to prevent a retain loop (otherwise the window controller owns a reference to the control which owns a reference to the window controller as the delegate).
So, in your above example, you would be better off exploring this concept by using a more real-world example where the delegate itself is retained by another object, which more closely mirrors the way that delegates are used in the wild.

Related

__weak IBOutlet vs IBOutlet? [duplicate]

I am developing exclusively for iOS 5 using ARC. Should IBOutlets to UIViews (and subclasses) be strong or weak?
The following:
#property (nonatomic, weak) IBOutlet UIButton *button;
Would get rid of all of this:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Are there any problems doing this? The templates are using strong as are the automatically generated properties created when connecting directly to the header from the 'Interface Builder' editor, but why? The UIViewController already has a strong reference to its view which retains its subviews.
WARNING, OUTDATED ANSWER: this answer is not up to date as per WWDC 2015, for the correct answer refer to the accepted answer (Daniel Hall) above. This answer will stay for record.
Summarized from the developer library:
From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because:
Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.
The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet).
#property (weak) IBOutlet MyView *viewContainerSubview;
#property (strong) IBOutlet MyOtherClass *topLevelObject;
The current recommended best practice from Apple is for IBOutlets to be strong unless weak is specifically needed to avoid a retain cycle. As Johannes mentioned above, this was commented on in the "Implementing UI Designs in Interface Builder" session from WWDC 2015 where an Apple Engineer said:
And the last option I want to point out is the storage type, which can
either be strong or weak. In general you should make your outlet
strong, especially if you are connecting an outlet to a subview or to
a constraint that's not always going to be retained by the view
hierarchy. The only time you really need to make an outlet weak is if
you have a custom view that references something back up the view
hierarchy and in general that's not recommended.
I asked about this on Twitter to an engineer on the IB team and he confirmed that strong should be the default and that the developer docs are being updated.
https://twitter.com/_danielhall/status/620716996326350848
https://twitter.com/_danielhall/status/620717252216623104
While the documentation recommends using weak on properties for subviews, since iOS 6 it seems to be fine to use strong (the default ownership qualifier) instead. That's caused by the change in UIViewController that views are not unloaded anymore.
Before iOS 6, if you kept strong links to subviews of the controller's view around, if the view controller's main view got unloaded, those would hold onto the subviews as long as the view controller is around.
Since iOS 6, views are not unloaded anymore, but loaded once and then stick around as long as their controller is there. So strong properties won't matter. They also won't create strong reference cycles, since they point down the strong reference graph.
That said, I am torn between using
#property (nonatomic, weak) IBOutlet UIButton *button;
and
#property (nonatomic) IBOutlet UIButton *button;
in iOS 6 and after:
Using weak clearly states that the controller doesn't want ownership of the button.
But omitting weak doesn't hurt in iOS 6 without view unloading, and is shorter. Some may point out that is also faster, but I have yet to encounter an app that is too slow because of weak IBOutlets.
Not using weak may be perceived as an error.
Bottom line: Since iOS 6 we can't get this wrong anymore as long as we don't use view unloading. Time to party. ;)
I don't see any problem with that. Pre-ARC, I've always made my IBOutlets assign, as they're already retained by their superviews. If you make them weak, you shouldn't have to nil them out in viewDidUnload, as you point out.
One caveat: You can support iOS 4.x in an ARC project, but if you do, you can't use weak, so you'd have to make them assign, in which case you'd still want to nil the reference in viewDidUnload to avoid a dangling pointer. Here's an example of a dangling pointer bug I've experienced:
A UIViewController has a UITextField for zip code. It uses CLLocationManager to reverse geocode the user's location and set the zip code. Here's the delegate callback:
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
Class geocoderClass = NSClassFromString(#"CLGeocoder");
if (geocoderClass && IsEmpty(self.zip.text)) {
id geocoder = [[geocoderClass alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if (self.zip && IsEmpty(self.zip.text)) {
self.zip.text = [[placemarks objectAtIndex:0] postalCode];
}
}];
}
[self.locationManager stopUpdatingLocation];
}
I found that if I dismissed this view at the right time and didn't nil self.zip in viewDidUnload, the delegate callback could throw a bad access exception on self.zip.text.
IBOutlet should be strong, for performance reason. See Storyboard Reference, Strong IBOutlet, Scene Dock in iOS 9
As explained in this paragraph, the outlets to subviews of the view
controller’s view can be weak, because these subviews are already
owned by the top-level object of the nib file. However, when an Outlet
is defined as a weak pointer and the pointer is set, ARC calls the
runtime function:
id objc_storeWeak(id *object, id value);
This adds the pointer
(object) to a table using the object value as a key. This table is
referred to as the weak table. ARC uses this table to store all the
weak pointers of your application. Now, when the object value is
deallocated, ARC will iterate over the weak table and set the weak
reference to nil. Alternatively, ARC can call:
void objc_destroyWeak(id * object)
Then, the object is
unregistered and objc_destroyWeak calls again:
objc_storeWeak(id *object, nil)
This book-keeping associated
with a weak reference can take 2–3 times longer over the release of a
strong reference. So, a weak reference introduces an overhead for the
runtime that you can avoid by simply defining outlets as strong.
As of Xcode 7, it suggests strong
If you watch WWDC 2015 session 407 Implementing UI Designs in Interface Builder, it suggests (transcript from http://asciiwwdc.com/2015/sessions/407)
And the last option I want to point out is the storage type, which can either be strong or weak.
In general you should make your outlet strong, especially if you are connecting an outlet to a sub view or to a constraint that's not always going to be retained by the view hierarchy.
The only time you really need to make an outlet weak is if you have a custom view that references something back up the view hierarchy and in general that's not recommended.
So I'm going to choose strong and I will click connect which will generate my outlet.
In iOS development NIB loading is a little bit different from Mac development.
In Mac development an IBOutlet is usually a weak reference: if you have a subclass of NSViewController only the top-level view will be retained and when you dealloc the controller all its subviews and outlets are freed automatically.
UiViewController use Key Value Coding to set the outlets using strong references. So when you dealloc your UIViewController, the top view will automatically deallocated, but you must also deallocate all its outlets in the dealloc method.
In this post from the Big Nerd Ranch, they cover this topic and also explain why using a strong reference in IBOutlet is not a good choice (even if it is recommended by Apple in this case).
One thing I wish to point out here, and that is, despite what the Apple engineers have stated in their own WWDC 2015 video here:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple keeps changing their mind on the subject, which tells us that there is no single right answer to this question. To show that even Apple engineers are split on this subject, take a look at Apple's most recent
sample code, and you'll see some people use weak, and some don't.
This Apple Pay example uses weak:
https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8
As does this picture-in-picture example:
https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4
As does the Lister example:
https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
As does the Core Location example:
https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6
As does the view controller previewing example:
https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5
As does the HomeKit example:
https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_Action_Sets_ActionSetViewController_swift-DontLinkElementID_23
All those are fully updated for iOS 9, and all use weak outlets. From this we learn that A. The issue is not as simple as some people make it out to be. B. Apple has changed their mind repeatedly, and C. You can use whatever makes you happy :)
Special thanks to Paul Hudson (author of www.hackingwithsift.com) who gave me the clarification, and references for this answer.
I hope this clarifies the subject a bit better!
Take care.
From WWDC 2015 there is a session on Implementing UI Designs in Interface Builder. Around the 32min mark he says that you always want to make your #IBOutlet strong.
Be aware, IBOutletCollection should be #property (strong, nonatomic).
It looks like something has changed over the years and now Apple recommends to use strong in general. The evidence on their WWDC session is in session 407 - Implementing UI Designs in Interface Builder and starts at 32:30. My note from what he says is (almost, if not exactly, quoting him):
outlet connections in general should be strong especially if we connect a subview or constraint that is not always retained by the
view hierarchy
weak outlet connection might be needed when creating custom views that has some reference to something back up in the view hierarchy
and in general it is not recommended
In other wards it should be always strong now as long as some of our custom view doesn't create a retain cycle with some of the view up in the view hierarchy
EDIT :
Some may ask the question. Does keeping it with a strong reference doesn't create a retain cycle as the root view controller and the owning view keeps the reference to it? Or why that changed happened?
I think the answer is earlier in this talk when they describe how the nibs are created from the xib. There is a separate nib created for a VC and for the view. I think this might be the reason why they change the recommendations. Still it would be nice to get a deeper explanation from Apple.
I think that most important information is:
Elements in xib are automatically in subviews of view. Subviews is NSArray. NSArray owns it's elements. etc have strong pointers on them. So in most cases you don't want to create another strong pointer (IBOutlet)
And with ARC you don't need to do anything in viewDidUnload

Explaning syntax for #property id<delegateName>

I see a lot of code references when writing delegates using something likes
#property (nonatomic, weak) id<mySuperCoolDelegate> delegate;
normally where id<mySuperCoolDelegate> is, is the data type of the property. So the questions are:
Is my understanding correct, that above syntax is telling the compiler data type of the id is mySuperCoolDelegate?
Any other examples where this sort of code (data type specified for id) could be used?
Thanks!
This piece of code is objective-c's way of implementing interfaces (as in Java or Go). using "id" means that you don't know at compile time what type of object it will be. But using the protocol in angle brackets you are telling the compiler that no matter what object it will be, it will need to support the 'mySuperCoolDelegate" protocol. If it doesn't - the compiler will let you know.
This syntax tells the compiler that delegate is of some kind of class (any class) that implements the mySuperCoolDelegate protocol.
This allows a certain component to notify another component on some event that happened without the need to know about the notified component (type-wise). (e.g. UITextView notifies its controller that the text has been changed without having a reference to that controller, only through the generic-typed delegate so the UITextView does not need to limit itself to a specific controller's type)
Also note that delegates are usually declared as weak (rather than strong). If an instance of UIViewController has a strong reference to a UITextView instance and that text view delegate (assume it is strong) is the controller instance then you will have a retaining cycle where both objects release will be dependent on the other object's release (which will never happen and leave you with a memory leak).
Short:
This tells the compiler that the property can be of any type as long as it implements the protocol mySuperCoolDelegate.
Still too short to be 100% accurate but easy to understand:
id is similar to NSObject*, meaning it is a reference to any kind of object (not only subclasses of NSObject, to be frank). Witin <> you declare which protocols the object has to conform to.
Example: It could be both:
#interface mySuperCoolClass : <mySuperCoolDelegate> ... #end
or
#interface somebodyElsesSuperCoolClass : <mySuperCoolDelegate> ... #end
Wherever you use that property, the compiler will allow you to access all methods that are declared in the related #protocol (most likely in some .h file that you need to #include).

In what order does setValue:forKey: search for the KVC-compliant method or ivar?

Some background:
I wrote a UIScrollView derived class with an outlet named contentView, similar to the following:
#interface MyScrollView : UIScrollView {
IBOutlet UIView * contentView;
}
...
#end
My outlet, in this case is an iVar, not a property. I made use of my class in Interface builder and connected a view to the contentView outlet. At runtime, however, I discovered that my iVar was still nil and was not set to the desired view object.
Some experimentation revealed that if I renamed the outlet or made my outlet a property instead of an iVar, all would work fine. Further research showed that with my outlet as an iVar named contentView, loading the nib would actually connect my desired view object to a private iVar in UIScrollView named _contentView.
I know that nib loading uses KVC to set values and that the KVC setValue:forKey: method will set a value using any of the following:
set{Key}: method
{key} iVar
_{key} iVar
I suspect, but cannot prove, that an attempt to find the set{Key}: method occurs first, and if that fails, an enumeration of iVars is undertaken to find the {key} or _{key} iVar next. This enumeration probably occurs in an order that processes iVars from superclasses before subclasses.
Is there a documented order in which the above candidates are attempted? In what order are members of superclasses attempted in relation to subclasses?
The specific search algorithm is documented in the Key-Value Coding Programming Guide.

Does IBOutlet imply __weak?

Just starting out with ARC. Pre-ARC, I would just simply declare my outlets as for example: IBOutlet UIButton *button; so I am not retaining it or anything. With ARC, not specifying weak or strong implies strong.
So if I do the same thing under ARC (i.e. IBOutlet UIButton *button;), does this mean button is a strong reference? or Do I have to explcility define it as weak?
In short, does IBOutlet imply __weak?
The word IBOutlet is actually defined as nothing:
#define IBOutlet
Xcode just uses the presence of this word in your code for purposes of allowing you to make connections in Interface Builder. A declaration of a variable or a property as an IBOutlet:
IBOutlet UIButton * button;
#property (...) IBOutlet UIButton * button;
therefore doesn't have any direct effect as far as ARC is concerned; it doesn't (although, conceivably, it could) translate into __weak or anything like that. The word itself is entirely gone from your source by the time the compiler gets it.
On the other hand, the fact that this variable or property is an outlet does have a meaningful effect on how you need to think about the memory management.
The implicit storage qualifier for an object variable declaration like IBOutlet UIButton * button; under ARC is __strong, as you said -- any object assigned to the variable will be considered "owned". Under MRR, the declaration is just a pointer; assigning to has no effect on the reference count/ownership of the assigned object -- it acts in the same way as an assign property.* So the meaning of the same ivar declaration changes between the two management systems.
Objects in a xib have owned/owner relationships that are formed by the view hierarchy; that is, parent views own their subviews. The top-level view in a xib is owned by the object known as File's Owner. This setup means that, generally speaking, your outlets to objects in an xib that are not top-level should be weak (under ARC) or assign (if a property under MRR). They are not owning relationships; they are essentially convenient indexes into the view list. This is Apple's recommendation:
...you don’t need strong references to objects lower down in the graph because they’re owned by their parents, and you should minimize the risk of creating strong reference cycles.
[...]Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create should will [sic] therefore typically be weak by default...
Your simple pointer IBOutlets, as I explained, acted -- for memory management purposes -- like weak properties,** which means that they were doing the right thing. The same declaration becomes probably the wrong thing when compiled under ARC.
In summary: IBOutlet does not translate into weak, but it does change the meaning of the pointer. Since the default memory management semantics of IBOutlet UIButton * button; change from "assign" under MRR to "owned" under ARC, and since IBOutlets should generally be non-owning, the presence of IBOutlet does indeed imply that the pointer should be declared __weak under ARC.†
*And similar to a weak property -- the only difference there is that weak pointers are set to nil when the object is deallocated.
**Except for the auto-nil part.
†Or, really, it should be a weak property.
No, IBOutlet is basically stripped when the code is compiled. It is however a helper for XCode so that it can know WHAT is an InterfaceBuilderOutlet.
Basically this word will let you connect the element in the Interface Builder.
By default it will still be strong (just imagine that word isn't there).
However it is suggested that you set it to weak because once something is connected to the interface builder, THAT interface will keep a strong reference to it, so there is no point at having a double strong reference, specially if that element is not meant to be kept alive when the interface has been unloaded.
Read this question which is exactly what you are looking for:
Should IBOutlets be strong or weak under ARC?
The IBOutlet keyword is only used to associate the object with an element in Interface Builder. It has nothing to do with weak or strong or ARC or memory management.

IBOutlet and lifetime qualifier in ARC

The template "MasterDetail" application writes an IBOutlet property in DetailViewController.h with strong qualifier.
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
While in Standford CS193 lessons from iTunesU (lesson 2 time 14:30) they set an IBOutlet as weak saying the label already has a strong pointer to it created by window.
Now, my question is how we have to declare storage for IBOutlet like Label and Button ? is it correct to use weak ? and if i'm on iOS4 is it ok use unsafe_unretained ?
EDIT-----
I found answer about strong or weak ... the main rules are :
Use strong for top level elements of the xib
Use weak for subelements like label buttons etc..
You can check documentation
But i still can't find something about iOS 4
Well, it's basically the same case as in MRC.
Your IBOutlets are usually inside your controller's view hierarchy and implicitly retained by their parent views. You can use assign (MRC) or weak or unsafe_unretained (ARC). In all cases your pointer is invalidated when you remove the object from your view hierarchy.
The only difference is that on MRC and ARC 4.0 the pointer is not set automatically to nil. It still contains a memory address but the address is invalid.
In any case, you shouldn't use the pointer any more.
Whenever you want to use the object even if it's not a part of your view hierarchy (usually every top level element in xib or when you are removing views from your hierarchy dynamically and you do not want them to be invalidated), you use retain or strong specifiers.
Note that many examples use strong for every IBOutlets and it's not an error. It's just not necessary.