Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIGestureRecognizer causes circular retain?

I was thinking, if you assign the target as self in the gesture recogniser's initWithTarget:action: method, will you cause a circular retain? Since self will retain the recogniser in self.gestureRecognizers and it's possible the gesture recogniser to also retain self in initWithTarget:action.

Would the following be a solution for it?

__weak VRDrawer* weakSelf = self;
UIGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] initWithTarget:weakSelf
                                                                      action:@selector(handleTap:)];
like image 861
Meda Avatar asked Jan 30 '13 20:01

Meda


2 Answers

I completely understand confirming something with the lack of documentation can feel unsettling. The important thing to note is that, by over a decade of convention, target-action relationships are never strong. Here's the relevant docs. Note the part that says:

Control objects do not (and should not) retain their targets.

"Retain…" in the MRC way of saying "Holds a strong reference to…"

Given this is the documented convention for this type of interaction, it's safe to assume that, if UIGestureRecognizer's target-action implementation did retain objects, that anomaly would be strange enough that it would show up in its docs.


P.S. You don't have to worry about the note that refers to controls retaining targets in memory-managed environments. "Memory-managed" refers to the (now depricated) garbage collection in Cocoa. Neither MRC or ARC is memory-managed.

like image 88
jemmons Avatar answered Oct 15 '22 16:10

jemmons


UIGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];

This does not retain self. It would also be noted in the docs

You need to add a recognizer to a view. That view will retain the recognizer. no retain cycle.

[aView addGestureRecognizer:tapRec];

addGestureRecognizer: docs do mention, that the view retains the recognizer


as you are using ARC, this is all you have to do

UIGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[aView addGestureRecognizer:tapRec];
like image 4
vikingosegundo Avatar answered Oct 15 '22 18:10

vikingosegundo