为什么在使用ARC时没有调用类dealloc?

时间:2012-06-09 19:35:04

标签: objective-c xcode cocoa-touch automatic-ref-counting dealloc

我有一个UIView子类,在其中我称之为另一个UIView子类。

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

这只是添加了一个图像,我会在删除之前制作动画。 我把它添加到原始的UIView中:

star1 = [[Stars alloc] init];
star1.center = self.center;
star1.delegate = self;
[self addSubview:star1];

使用如下动画开始删除过程:

if (CGRectIntersectsRect(thumbR, star1.frame)) {
        if (!star1.gained) {
            star1.gained = YES;
            [star1 animateAndRemove];
        }
    }

当完成时调用它:

- (void)removeStar:(Stars *)star
{
    star.delegate = nil;
    [star removeFromSuperview];
    star = nil;
}

现在,当类被删除时,不会调用dealloc中的NSLog,而是将其设置为nil。为什么不呢?

我实际上看到的第一个UIView我正在加载这个Stars类。当我认为它应该时,那个也不是dealloc'ing。 当我通过alloc重新分配包含的UIView并再次启动它时,两个dealloc方法都是完整的。

当我从视图中删除并设置为nil时,我错误地认为这是dealloc吗?

1 个答案:

答案 0 :(得分:1)

考虑您的removeStar

- (void)removeStar:(Stars *)star
{
   star.delegate = nil;
   [star removeFromSuperview];
   star = nil;
}

这必须使用以下行的调用从某处调用:

[<some object reference> removeStar:<some Stars reference>]

现在star中的变量removeStar是该方法的 local 。调用该方法时,此变量初始化为传入的Stars引用 - 因此您有一个附加引用。超过removeStar的调用者所引用的引用,调用该方法的Stars实例。

然后,当您将nil分配给此本地变量时,您只会删除此附加引用。 removeStar的来电者仍有参考。所以没有dealloc

猜测removeStar的来电者可能是该实例的所有者,也需要删除其引用。