Reputation: 10398
I have a UIView subclass, and within this I call this other UIView subclass.
Stars.h
@interface Stars : UIView {
BOOL _gained;
}
@property (nonatomic, weak) id<NSObject> delegate;
@property (nonatomic) BOOL gained;
-(void)animateAndRemove;
@end
Stars.m
#import "Stars.h"
@implementation Stars
@synthesize delegate = _delegate;
@synthesize gained = _gained;
- (id)initWithFrame:(CGRect)frame
{
frame.size.width = 31;
frame.size.height = 30;
self = [super initWithFrame:frame];
if (self) {
_gained = NO;
self.backgroundColor = [UIColor clearColor];
// Add star
UIImageView *star = [[UIImageView alloc] initWithFrame:frame];
[star setImage:[UIImage imageNamed:@"star-sticker"]];
[self addSubview:star];
}
return self;
}
- (void)animateAndRemove
{
[UIView animateWithDuration:0.2
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
self.transform = transform;
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
self.transform = transform;
CGAffineTransform move = CGAffineTransformMakeTranslation(0, -200);
self.transform = move;
self.alpha = 0.0;
}
completion:^(BOOL finished){
if ([self.delegate respondsToSelector:@selector(removeStar:)]) {
[self.delegate performSelector:@selector(removeStar:) withObject:self];
}
}];
}];
}
- (void)dealloc
{
NSLog(@"%s",__FUNCTION__);
}
@end
This simply adds an image, which I animate before removing. I add this to the original UIView like this:
star1 = [[Stars alloc] init];
star1.center = self.center;
star1.delegate = self;
[self addSubview:star1];
And start the removal process with the animation like this:
if (CGRectIntersectsRect(thumbR, star1.frame)) {
if (!star1.gained) {
star1.gained = YES;
[star1 animateAndRemove];
}
}
Which when complete calls this:
- (void)removeStar:(Stars *)star
{
star.delegate = nil;
[star removeFromSuperview];
star = nil;
}
Now the NSLog in dealloc isn't called when the class is removedFromSuperview and set to nil. Why not?
I'm actually seeing the same thing with the first UIView that i'm loading this Stars class into. That one is also not dealloc'ing when I think it should. Both dealloc methods are intact called when I reassign the containing UIView by alloc and initing it again.
Am I wrong to expect this to dealloc when it's been removed from view and set to nil?
Upvotes: 0
Views: 3492
Reputation: 53000
Consider your removeStar
:
- (void)removeStar:(Stars *)star
{
star.delegate = nil;
[star removeFromSuperview];
star = nil;
}
This must be called from somewhere using a call along the lines of:
[<some object reference> removeStar:<some Stars reference>]
Now the variable star
in removeStar
is local to that method. When the method is called this variable is initialized to the passed in Stars
reference - so you have an additional reference. over and above the reference the caller of removeStar
has, to the Stars
instance the method is called with.
When you then assign nil
to this local variable you only remove this additional reference. The caller of removeStar
still has its reference. So no dealloc
.
Guessing: The caller of removeStar
is probably the owner of the instance and needs to remove its reference as well.
Upvotes: 1