English 中文(简体)
UIView isn t released. Calling delegate with self, and using UIView commitAnimations adds retain count
原标题:

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.

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 ;):

The view

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

}

I found out that after the

[UIView commitAnimations];

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

[delegate viewWasAnimated:self];

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.

最佳回答

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];
  }
}

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

In the dealloc method of the UIViewController do

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

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];
  }
}
问题回答

First off i guess it s a typo but:

 [self.view addSubview:adview]; 

should be

 [self.view addSubview:myview]; 

About your question:

1-Put MYView *myview; in your viewcontroller.h

2-Before you release the viewcontroller, call:

[myview removeFromSuperView];

This should deallocate your subview.(if there are no other additional retains)

Good luck.





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签