J'ai une vue qui est ajoutée en tant que sous-vue dans un viewcontroller. La sous-vue a des méthodes délégués et le viewcontroller est associé à son délégué. La sous-vue possède une animation et appelle une méthode déléguée lorsque l'animation est terminée. Le problème est que lorsque le contrôleur de vue est retiré de la vue par le contrôleur de navigation, la sous-vue n'est pas libérée. Probablement parce que le nombre de versions est> 0. Lorsque le viewcontroller est retiré de la vue avant la fin de l'animation de sous-vue, la sous-vue tente d'appeler la méthode delegate (qui est le viewcontroller qui n'existe plus) et j'obtiens un EXC_BAD_ACCESS.UIView n'est pas libéré. Appel de délégué avec self, et en utilisant UIView commitAnimations ajoute le nombre de retenue
Peut-être un échantillon clarifier les choses;):
La vue
- (void)somefunction {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(viewDidAnimate:finished:context:)];
[UIView setAnimationDuration:0.3];
self.frame = CGRectMake(0, 320, 320, 47);
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView commitAnimations];
}
-(void)viewDidAnimate:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
if (self.delegate != NULL && [self.delegate respondsToSelector:@selector(viewWasAnimated:)]) {
[delegate viewWasAnimated:self];
}
}
viewcontroller
- (void)viewDidLoad{
[super viewDidLoad];
MYView *myview = [[MYView alloc] init];
myview.delegate = self;
[self.view addSubview:myview];
[myview release];
}
- (void)viewWasAnimated:(MYView *)view{
}
J'ai découvert qu'après la
[UIView commitAnimations];
ligne le retainCount la vue est 2, et après le
[delegate viewWasAnimated:self];
le nombre de versions est 3. Donc c'est probablement pourquoi la vue n'est pas libérée. Je sais que je ne suis pas censé regarder les comptes de retenue, mais je ne sais pas quoi faire d'autre.
D'accord c'est ce que je pensais. J'ai ajouté le chèque pour voir si l'aperçu est nul. Cela a résolu un problème que j'ai. Je suppose que l'animation UIView libère ma vue quand c'est fait. Toujours le [délégué viewWasAnimated: self]; L'appel ajoute un compte de retenue afin que la vue ne soit jamais libérée. –
Définissez-vous le délégué avec retain ou assign dans la déclaration @property. Assurez-vous de le déclarer comme assign, car vous créerez une boucle de conservation si vous ne le faites pas. Puisque le délégué sera retenu par le point de vue et que le point de vue est conservé par le délégué, aucun des points ne sera jamais publié. Vous pouvez facilement voir qui retient votre point de vue si vous ne pouvez pas comprendre en remplaçant les méthodes suivantes sur MyView et la fixation d'un point de rupture pour voir qui fait Retain et la libération des appels - (id) retenir { return [super retain]; } - (vide) libération { [super release]; } Bonne chance! –
Le délégué a été déclaré comme assing. Mais grâce aux appels de libération retenus, j'ai découvert que j'avais aussi une minuterie qui retenait la vue. J'ai ajouté une fonction [myview cancelTimer] qui invalide le timer. J'appelle cette fonction dans les méthodes viewWillDisappear du viewcontroller contenant myview. Cela a fait l'affaire. Merci! –