UIView没有发布.用self调用委托,并使用UIView commitAnimations添加保留计数 [英] UIView isn't released. Calling delegate with self, and using UIView commitAnimations adds retain count
问题描述
我有一个视图作为子视图添加到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屋!