Possible circular reference? - ios

I have an object called PanelView in Cocoa Touch which has a UINavigationController instance variable. At some point in my app, when the UINavigationController is presented as modal view, I send in a PanelView object as a parameter to the rootViewController of the UINavigationController where it is stored as an instance variable. I declare it how I would normally in the .h file:
PanelView *_panelView;
#property(nonatomic, strong) PanelView *panelView;
And in the .m file:
#synthesize panelView = _panelView;
So far I've had no side effects, but I'm wondering if I'm declaring this correctly as it might be a circular reference. What is the correct way to declare this variable?

Objective-C has evolved to be pretty forgiving on syntax, especially on iOS. You don't actually need to declare the variable that's acting as the backing store for your #property -- it will be synthesized for you.
It used to be the case that if you declared both a getter and a setter, then you would need to insert the #synthesize in your #implementation block, as you have it above. I just tried it out in Xcode 7.1 to double-check, and the compiler didn't complain for either a Cocoa Touch project or a command-line app project.
It seems from your follow-up question that you need to sort out the ownership of your data. Circular references in and of themselves usually aren't the problem. Keeping strong circular references is. That's how you get memory cycles that lead to leaks.
I would advise that you change the UINavigationView's reference to be a weak reference, since it the PanelView is guaranteed to be in existence as long as the UINavigationView is in existence.

Related

Why some Outlets are made strong references even tough the documentation specifies that outlets should be weak reference

Hi I am a newbie to iOS programming. I know what a strong and weak reference is. But I get confused which type of reference to use when I have to deal with outlets. After going through the documentation which states that
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.
So what I understood after going through the above statement is that the Outlets that we create should typically be weak by default.
But while studying some tutorials I have come across the code where people have declared an outlet as strong reference. For example consider the following code :
#interface AboutViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#end
The code :
#property (nonatomic, strong) IBOutlet UIWebView *webView;
says that our AboutViewController has an UIWebView object.
But why we need a strong reference here for the UIView object?? As the document states shouldn't this be an weak reference ?
Also please explain in the documentation statement which I have quoted above what does the File’s Owner to top-level objects mean?.
I have gone through many of the similar questions on this website but none of them helped me to clear my doubt. So please help. Thanks in advance :)
What to use for non top level GUI elements - strong or weak - depends on how you are going to use their outlets. If you have a weak reference
#property (nonatomic, weak) IBOutlet UIWebView *webView;
then after calling method
[webView removeFromSupeview];
your webView will be nil and it will be impossible to restore UIWebView just by adding
[self.view addSubview:webView];
If this is appropriate for you - it is better to use weak because you will free webView's memory when you do not need it.
On the other hand, in case of a strong reference after
[webView removeFromSupeview];
webView will still have referenceCount > 0 and webView will be deallocated only if owner will free it explicitly
self.webView = nil;
or in the owner's
- (void)dealloc
together with the owner itself.
Usually there is no difference if you have static GUI. If you want to remove (not hide) some views add be able to add them later - strong references should be used.
Top level objects should be retained strong. Like
#property(nonatomic,retain) UIView *view;
in UIViewController.
It usually doesn't hurt to use a strong reference in place of a weak one in the case of outlets like this. And in some cases, you do need a strong reference.
The idea is that something has to keep a strong reference to the object at all times or it could vanish. If the object is a view that is a subview of another view, then that superview will keep a strong reference to it and so you can use a weak reference. But, if you're going to do something else with that view, such as remove it from it's superview for some reason (maybe to reuse it elsewhere, or something), then you'll want to use a strong property so that there's always something holding it strongly.
Regarding the File Owner issue, that's because the top level object (most likely a view) does not have a superview holding on to it, so you need to use a strong property so that you're holding on to it.
The simple answer is that unless you are supporting iOS 5, outlets should always be strong.
The purpose of weak outlets was so that in iOS5, if the system unloaded the view controller's view to save memory, any outlets pointing to subviews would be automatically released.
In iOS 6 and later, the system never unloads the view controller's view (viewDidUnload is never called) because Apple found a way to release most of the memory used by a view without releasing the view itself.
Consequently, the outlets in a view controller will never normally need to be released until the view controller itself is released, at which point ARC will clean up all the outlets anyway.
So just use strong for all your outlets and you won't have to worry about obscure bugs or compiler warnings due to using the wrong reference type.
Quoting from Apple's Resource Programming Guide,
Each time you ask the NSBundle or NSNib class to load a nib file, the underlying code creates a new copy of the objects in that file and returns them to you. You need to ensure that you maintain the new object graph as long as necessary, and disown it when you are finished with it. You typically need strong references to top-level objects to ensure that they are not deallocated; 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.
In case of framework classes like UIViewController the top-level object for the NIB file is the view property. If you check in the documentation it is declared as retain(similar to strong).
#property(nonatomic, retain) UIView *view
So any subviews to this container view should be automatically owned by it. If you now declare these subview outlets as strong they will create a strong cycle and cause memory leaks when the framework tries to cleanup the container view. To avoid these strong cycles all subviews (or non top level objects) should be declared as weak properties.
When can you declare IBOutlet's as strong
Outlets should be changed to strong when the outlet should be considered to own the referenced object:
As indicated previously, this is often the case with File’s Owner—top level objects in a nib file are frequently considered to be owned by the File’s Owner.
You may in some situations need an object from a nib file to exist outside of its original container. For example, you might have an outlet for a view that can be temporarily removed from its initial view hierarchy and must therefore be maintained independently.
You need to check in your code if webView object qualifies for case2 as above. If not the tutorial has got this one wrong and it actually should be weak.
Hope that helps!

Properties vs instance variables, poor class encapsulation?

I'm a fan of not exposing class variables unless needed. In most objective-c code I see, the variables are declared as properties even if they are never to be used by an outsider.
#interface DetailViewController : UIViewController {
__weak IBOutlet UILabel *name;
}
vs
#interface DetailViewController : UIViewController
#property (weak, nonatomic) UILabel *name;
As a student of Software Engineering, this seams to me to be a pretty bad violation of principles such as encapsulation and could potentially lead to unwanted coupling in a large project.
I do understand the KVC aspects of using properties, but not why one would expose variables which are clearly only meant to be used internally in the class, such as the UILabel above.
Could someone explain why this is the preferred way when working with Objective-C on iOS?
Properties encapsulate the memory management (eg assign, retain, copy, strong, weak) of a iVar, while direct access to an iVar (instance variable) does not. This greatly reduces memory bugs.
Non-public properties can be declared at the top of the .m so there's no reason for them to be in the header:
#interface DetailViewController ()
#property (weak, nonatomic) NSString *name;
#end
Properties do create ivars that can be accessed. For the example above, with an explicitly synthesized property, the ivar would be named name while an implicitly synthesized synthesized property will have a leading underscore _name.
IBOutlets are declared in the header even though other classes don't need access to them as they are required so that Interface Builder connect to them and the nib loading system can populate the outlets. IBOutlets are most often going to be views, such as your UILabel.
Edit:
The previous paragraph about IBOulets is a legacy method required for Xcode 3 and earlier. However, newer versions of Xcode can use outlets defined in the implementation file just as the property above thanks to tighter integration of the InterfaceBuilder to the rest of the IDE.
What you see is an old style. Earlier Objective-C compilers required that you declare instance variables in the interface. However, by default they are #protected, so not everyone can just use them.
Current best practice is that you don't declare instance variables at all but use properties, unless you need to declare them (if you have a custom getter for a readonly property, or both custom getter and setter for a readwrite property, no instance variable is generated automatically), that you declare them in your .m file unless someone really needs to access them, that you declare properties and methods in your .m file unless someone needs to access them, and that you don't declare methods at all unless needed.
It's also quite common to declare a property as readonly in the header file, and redeclare it as read/write in the implementation.
In other words, hide what you can hide.
The first example indicates that you want to use the label as an outlet for a Xib or Storyboard. This answer sheds some light on that case: https://stackoverflow.com/a/1236985/171933
In general, however, you don't need to declare internal instance variables as properties. Actually, you can move them completely out of the header by putting them into your .m file like so:
#implementation DetailViewController
{
NSInteger _someValue;
UILabel *_someLabel;
}
That way you can really only keep the things in the header that should be visible to the outside. And those things would typically either be properties or plain old methods.

Correct way to declare properties

I am little confused about specifying strong, copy, or assign and not specifying them. We don't use NIB files. My colleague always use following - he says iOS detects it and use it automatically strong, weak etc.
#interface viewController : UIViewController
#property (nonatomic) UIImageView *imageView1;
#property (nonatomic) NSUInteger num;
#property (nonatomic) NSArray *array;
#end
I prefer following way doing it.
#interface viewController : UIViewController
#property (nonatomic, strong) UIImageView *imageView1;
#property (nonatomic, assign) NSUInteger num;
#property (nonatomic, copy) NSArray *array;
#end
Which one is better programming style? First option always have strong type as it defaults but I always specifies them explicitly.
As pointed out in earlier answers, in Objective C properties are by default,
atomic, strong/retain, readwrite --> For pointer types
atomic, assign, readwrite --> For primitive types
Property types weak, copy need to be explicitly specified by the programmer and in no way gets automatically decided.
What does each mean,
strong/retain referenced objects are kept alive in the memory until specified.
weak referenced objects will be destroyed when there is no strong reference. Typically used to reference delegate objects.
copy will create a shallow copy of the object getting assigned to the property.
assign/usafe_unretained(ARC) assigns the value. If used in case of pointer types this is an unsafe unretained assignment of the pointer. In ARC, typically use weak for pointer types because it will make the ivar=nil once weak referenced object is destroyed. assign in this case will lead to dangling pointer.
Personally, I prefer specifying property types even if it strong by default. This adds readability, which comes handy specially when profiling application for memory leaks or debugging crashes.
You can read more about properties here.
Hope that helps.
With ARC, strong is the default so the two are technically the same. From the Transitioning to ARC Release Notes:
__strong is the default. An object remains “alive” as long as there is a strong pointer to it.
Note that ARC will NOT automatically detect when something needs to be weak, however.
I tend to be explicit, like your second example, but I think it's mostly a matter of style/habit.
The default for a property is strongand for a variable is __strong too. In your current example the recommended property would actually be weak, but strong is acceptable too.
For properties of non-primitives you should no longer use assign, but rather unsafe_unretained. Practically they're the same, but the latter lets you know that you're using an object unsafely.
The copy property means that an object is copied (using the copy method) and not retained. It's recommended for classes such as NSString and NSArray, which have mutable forms. This is because you don't want to retain what you think is an immutable string but is actually being changed elsewhere.
The assign property declaration should be used only for primitive types and structs, e.g. int and CGSize.

What's the difference between the following state?

maybe it's a little childish question, but I really want to know the detail. I've just seen this code:
#implementation SimpleMainViewController
{
SimpleTableViewController *simpleTableViewController;
AboutViewController *aboutViewController;
}
what's the difference between this and the following one?
#interface SimpleMainViewController : UIViewController
#property(nonatomic,retain) SimpleTableViewController *simpleTableViewController;
#property(nonatomic,retain) AboutViewController *aboutViewController;
#implementation SimpleMainViewController
#synthesize simpleTableViewController;
#synthesize aboutViewController;
Thanks in forward.
The first one is only visible and acceseable from inside the implemented class. It is called an instance variable.
Whereas the property is visible to other classes as well. A property is backed by an iVar too. The #synthesize is doing this behind the scenes. In your case the backing iVar would be accessable with the name of the property (e.g. simpleViewController). But one should access a property via self (e.g. self.simpleViewController) for simpler memory management and to distinguish it from an normal iVar. The #synthesize will generate getter and setters to the iVar and will do memory management according to the property declaration (here retain).
Nowadays you do not even need a #synthesize any more. Just declare a property. The compiler will create the property with an backing iVar with a prefix underscore. So one could access it either via self.simpleTableViewController or via _simpleTableViewController.

Setting strong references objects to nil with ARC enabled?

I am developing an iPhone app with ARC option enabled. i am creating IBOutlets in .h files which are connected from file owners icon to .xib elements.for eg.
IBOutlet UIButton *bt;
#property(nonatomic,retain)IBOutlet UIButton *bt;
in .m file, i am doing
#synthesize bt;
Is there a need to explicitly set bt to nil in viewDidUnload method? i.e. self.bt = nil; in viewDidUnload?
Also, do I need to write dealloc method with ARC option enabled? When should I make IBOutlets elements as strong and weak references with ARC enabled?
There's a difference between the need to put your outlets to nil in viewDidUnload and dealloc
Having ARC means you don't need to write that in your dealloc method (it gets done automatically), however the viewDidUnload method serves another purpose, and it is to free memory that the application isn't using when a memory warning occurs.
dealloc is still needed in some cases, for example, when your class is registered for a notification, or when your class is someone else's delegate and you don't want some glitchy callback giving you a bad access
When you get a memory warning, all the UIViewControllers not being displayed will unload their view and call that method to free up memory. If you are still retaining outlets (like buttons, tables and etc) they will not get released, thus, killing the purpose of the viewDidUnload method.
When using ARC there is no need to use modifiers like retain or copy, for example. That kind of memory managment is done automatically using the strong and weak modifiers.
You also don't have to worry about writing dealloc methods.
strong is kind of the equivalent of retain, so you should mark your outlets with it
#property(nonatomic, strong) IBOutlet UIButton *bt;
That's the way interface builder creates them by default.
I won't go into detail about their semantic differences, but you should really have a look at Apple's guide on transitioning to ARC if you want to know what's going on and read about the specifics of strong and weak modifiers.
EDIT:
Sorry, interface builder creates outlets with weak by default.
EDIT 2:
strong and retain are indeed 100% identical. (thanks to #Adam)
EDIT 3:
You set your pointers to nil to avoid getting any message sent to deallocated instance or BAD_ACCESS_EXCEPTION errors.
If you are actually using ARC, you should make your outlets (nonatomic, weak) instead of (nonatomic, strong). By using the weak zeroing pointers, what the compiler does is automatically set your outlets to nil when nothing else references them.
So, summing up, if you don't use weak properties, you should set your pointers to nil.

Resources