UIView没有发布.用self调用委托,并使用UIView commitAnimations添加保留计数 [英] UIView isn't released. Calling delegate with self, and using UIView commitAnimations adds retain count

查看:96
本文介绍了UIView没有发布.用self调用委托,并使用UIView commitAnimations添加保留计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视图作为子视图添加到viewcontroller中.子视图具有委托方法,并且将视图控制器作为其委托.子视图有一个动画,并在动画完成后调用委托方法.

I have a view that is added as a subview in a viewcontroller. The subview has delegates methods and the viewcontroller is assinged as its delegate. The subview has a animation and calls a delegate method when the animation is finished.

问题是,当导航控制器从视图中删除视图控制器时,子视图不会被释放.可能是因为它的发布计数大于0.当在子视图动画完成之前将视图控制器从视图中移除时,子视图会尝试调用委托(不再存在的视图控制器)方法,并且我得到EXC_BAD_ACCESS.

The problem is that when the viewcontroller is removed from the view by the navigationcontroller the subview isn't deallocated. Probably because it's release count is >0. When the viewcontroller is removed from view before the subview animation finishes the subview tries to call the delegate (which is the viewcontroller which doesn't exist anymore) method and i get a EXC_BAD_ACCESS.

也许一些示例可以澄清问题;):

Maybe some sample will clarify things ;):

视图

- (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

viewcontroller

- (void)viewDidLoad{
  [super viewDidLoad];
  MYView *myview = [[MYView alloc] init];
  myview.delegate = self;
  [self.view addSubview:myview]; 
  [myview release];
}

- (void)viewWasAnimated:(MYView *)view{

}

我发现

[UIView commitAnimations];

将视图的retainCount设置为2,并在

line the retainCount of the view is 2, and after the

[delegate viewWasAnimated:self];

释放计数为3.因此,这可能就是为什么不释放视图的原因.我知道我不应该查看保留计数,但不知道还要做什么.

the release count is 3. So this is probably why the view isn't released. I know I am not supposed to look at retain counts but don't know what else to do.

推荐答案

您的视图未取消分配,因为UIView beginAnimation块会在整个动画持续时间内保留该视图.因此,如果可以在动画过程中释放控制器,则可以在dealloc中从控制器的视图中删除UIView,并在animationDidStop:方法中检查超级视图是否等于nil(如果不是),则不要发送消息

Your view is not deallocated because the UIView beginAnimation Block retains it for the whole animation duration. So if your controller can be released during your animation you can remove the UIView from the controller's view in the dealloc and in the animationDidStop: method check if the superview is equal to nil if so, then don't send the message

-(void)viewDidAnimate:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
  if (self.superview != nil && self.delegate != NULL && [self.delegate respondsToSelector:@selector(viewWasAnimated:)] ) {
    [delegate viewWasAnimated:self];
  }
}

您可以采取的另一种方法是取消UIView动画,但这并不直观.

Another approach you could take is to cancel the UIView animation but that is not as intuitive.

UIViewController的dealloc方法中

In the dealloc method of the UIViewController do

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView commitAnimations];

这将取消当前动画.并且您会在animationDidStop消息中收到finished == NO

This will cancel the current animations. And you will receive finished == NO in the animationDidStop message

(void)viewDidAnimate:(NSString *)animationID finished:(BOOL)finished context:(void *)context{
  if ( finished && self.delegate != NULL && [self.delegate respondsToSelector:@selector(viewWasAnimated:)] ) {
    [delegate viewWasAnimated:self];
  }
}

这篇关于UIView没有发布.用self调用委托,并使用UIView commitAnimations添加保留计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆