Why not just declare all @properties as strong and nil them?

An application that I am working on, that uses ARC and needs to support iOS 4.3 and iOS 5, declares every outlet as @property (strong, nonatomic) IBOutlet in the .h file.

e.g.

// myClass.h
@property (strong, nonatomic) IBOutlet UITextView *myTextview;

I know that with ARC only properties which do not hold a strong reference to an object are released. As a result, the App relies on - (void)viewDidUnload to set the property myTextview to nil.

i.e.

// myClass.m

- (void)viewDidUnload
{ 
[super viewDidUnload];
self.myTextview = nil;  
}

I know, from Apple's Documentation, that Outlets should generally be weak except those from File's Owner ( i.e. A Runtime Object that owns the contents of the iOS Storyboard scene) to Top-Level Objects (my rule of thumb is to use anything that appears in the window with File's Owner, First Responder and View).

Anything I add to the view will be a subview and thus is retained by it's direct superview, meaning a weak reference should be used.

I am also aware that - (void)viewDidUnload is deprecated in iOS 6 and is not called.

1st Question : What are the issues with taking the approach of declaring every outlet as a strong property and setting it to nil in viewDidUnload, apart from the fact that viewDidUnload is deprecated in iOS 6?

My intuition tells me that it is because situations arise where you can set a pointer to nil, before viewDidUnload is called. So you should, to free up memory on the heap. Is there a noticable performance change if this is the case?

2nd Question : Should I go back throughout the project and change strong to weak? Why? Is it worth the time?

3rd Question : If I was to declare the property in a class extension, to 'hide' it, how does this affect my rule of thumb for deciding on when to use strong or weak.

I know there are many threads here that discuss this issue. But many I've found are out of date, and do not address this issue directly. Thanks.

Answers


First, a few of your presumptions need addressing:

I know that ARC only releases properties which do not hold a strong reference to an object. As a result, the App relies on - (void)viewDidUnload to set the property myTextview to nil.

Not quite. ARC never retained weak properties in the first place. As for strong properties, ARC still releases them, but not until dealloc is called.

viewDidUnload was never used to prevent leaks. It was essentially an optimization, and one that Apple decided was no longer worth the trouble. To understand, consider the standard lifecycle of a pre-iOS6 view controller:

1. Allocated 2a. View Loaded 2b. View Unloaded 3. Deallocated

Where 2a and 2b could be repeated any number of times. For example, a view controller at the bottom of a navigation stack (its view being hidden) could have its view unloaded in low memory situations. It would then be reloaded the next its view became visible.

The method was essentially saying "Hey view controller programmer, we're running low on memory, and nobody can see me anyways, so I'm releasing my view. If you could do the same for your strong properties, that would be great."

That process had subtleties and was generally confusing. As a result of the tediousness, Apple deprecated it. Views are no longer unloaded, so there's no point in implementing it. The key point is that all your strong properties will still be released in ARC's dealloc method.

I know that Outlets should generally be weak...

Why do you know that? There's nothing special about outlets. The 'IBOutlet' keyword is really just for Xcode's benefit when designing things with its visual tools. It has no effect on the compiled code. So, when thinking about strong vs weak outlets, use the same considerations that you do for any other property, namely "do I need this to exists, or am I okay with it disappearing on me?".

What are the issues with taking the approach of declaring every outlet as a strong property and setting it to nil in viewDidUnload, apart from the fact that viewDidUnload is deprecated in iOS 6?

There are no issues with that. If you want your properties to exists as long as your controller, then use strong. viewDidUnload has nothing to do with this. On older iOS versions, you could release strong outlets in viewDidUnload if you want.

Should I go back throughout the project and change strong to weak? Why? Is it worth the time?

Again, just use whichever qualifier makes sense for your use case. You're almost always safe using strong for you outlets.

If I was to declare the property in a class extension, to 'hide' it, how does this affect my rule of thumb for deciding on when to use strong or weak.

There's no difference.


Need Your Help

How to display image in place of checkbox?

jquery css html5

I want to display green checked image when checkbox is checked and when not checked empty box. I tried to put checkbox in div and set div's background but it is not helping me out. Any idea what to...

Knockout binding on foreach item not updating

javascript knockout.js

I am using the click event on a button to set the value of an item that was generated using a foreach.