My first impression is that you can try to access the StandardPanelView standard that has just been released.
- What could be wrong, which leads to the failure of the internal call [UIViewGestures) removeAllGestureRecognizers]. One of the theories is that some kind of gesture in an array of gestures is freed up somewhere else.
This will not happen because the UIGestureRecognizer has been released. UIView strongly contains UIGestureRecognizers in NSArray. They will not be freed while they are still in the array.
However, the UIGestureRecognizer delegate may have received an exemption. This is only a property (assign), which means that it is not strongly held, and if the delegate is released, it will be a dangling pointer. So, if a delegate is used in [NSArray makeObjectsPerformSelector:] , this can happen.
- When a UIView contains subviews, how does the process of the release process go?
Objects are exempted from 'parent' to 'child', i.e. the supervisor is released, then submits, then the gesture recognizers. (Although regardless of whether the sub-items are freed up, before gesture recognizers are implementation details, so you probably shouldn't depend on it).
We can see this in a simple sample controller:
// The UIView that will be used as the main view
// This is the superview
@interface MyView: UIView
@end
@implementation MyView
- (void) dealloc {
NSLog (@ "Dealloc MyView");
}
@end
// This view will be put inside MyView to be used as a subview
@interface MySubview: UIView
@end
@implementation MySubview
- (void) dealloc {
NSLog (@ "Dealloc MySubview");
}
@end
// This is the gesture recognizer that we will use
// We will give one to each view, and see when it is deallocated
@interface MyGestureRecognizer: UIGestureRecognizer
@property (nonatomic, copy) NSString * tag;
@end
@implementation MyGestureRecognizer
@synthesize tag;
- (void) dealloc {
NSLog (@ "Dealloc MyGestureRecognizer tag:% @", tag);
}
@end
// Just a test view controller that we will push on / pop off the screen to take a look at the deallocations
@interface TestViewController: UIViewController
@end
@implementation TestViewController
- (void) loadView {
self.view = [[MyView alloc] init];
MyGestureRecognizer * recognizer = [[MyGestureRecognizer alloc] initWithTarget: self action: @selector (doStuff)];
recognizer.tag = @ "MyViewGestureRecognizer";
recognizer.delegate = self;
[self.view addGestureRecognizer: recognizer];
}
- (void) viewDidLoad {
[super viewDidLoad];
MySubview * subview = [[MySubview alloc] init];
MyGestureRecognizer * recognizer = [[MyGestureRecognizer alloc] initWithTarget: self action: @selector (doStuff)];
recognizer.tag = @ "MySubviewGestureRecognizer";
recognizer.delegate = self;
[subview addGestureRecognizer: recognizer];
[self.view addSubview: subview];
}
- (void) doStuff {
// we don't actually care what it does
}
@end
All we do is add MyView as the main view for TestViewController, and then add MySubview inside MyView. We also attach MyGestureRecognizer to each of the views.
When we push it from the screen, our output to the log:
Dealloc TestViewController
Dealloc myview
Dealloc MySubview
Dealloc MyGestureRecognizer tag: MySubviewGestureRecognizer
Dealloc MyGestureRecognizer tag: MyViewGestureRecognizer
Sorry for the long answer ... It has been about three months since you posted it, so maybe you have already solved the problem, but if someone else stumbles upon this answer, I hope this helps .