I have the following property defined in the header file of one of my ViewControllers (VC):
@property(nonatomic, retain) IBOutlet UIImageView *articleImageView1;
In the implementation of the VC, in the method viewDidLoad
, I attach TapRecognizers to these properties:
UITapGestureRecognizer *captureImage1TapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
[self.articleImageView1 addGestureRecognizer:captureImage1TapRecognizer];
The VC holds strongly the UIImageView
.
- Does this
UIImageView
also contain the VC strongly through the GestureRecognizer?
- Is this then a classical example of a retain cycle?
If so, would this be correct solution?
-(void)viewDidUnload {
...
[self setArticleImageView1:nil];
...
[super viewDidUnload];
}
From Concepts of Obj-C programming on target - action pattern:
Control objects do not (and should not) retain their targets
Thus UIGestureRecognizer
does not retain VC and there is no retain cycle.
Additional remarks
As pointed out by skyddict, -viewDidUnload
has been deprecated and you should use -dealloc
to perform cleanup. However, you don't need to nil
your properties - they are released when object is destroyed.
First of all, all IBOutlet
properties should be declared as weak
and not retain
. Secondly, viewDidUnload
has been deprecated since iOS 6.0. You should use dealloc
in order to do the final cleanup for any NSObject
subclass (you override this method to dispose of resources other than the object’s instance variables).
If you have the image view declared as weak
, there won't be any retain cycles.You don't have to retain the IBOutlet
(since it's already retained by it's superview). If you make IBOutlet
s weak, you won't have to nil them out as you point out.
You don't have a strong reference cycle here. This is a solution that should work just fine.
The view controller has a strong reference to the UIImageView
. The UIImageView
holds its gesture recognizers in an array (strong reference as well), but the gesture recognizer does not hold target/action or delegate strongly.
You may hold onto the UIImageView
via a weak reference, but since iOS 6 views are not unloaded anymore, so it won't make any difference for memory management.