0

UIView サブクラスがあり、その中でこの別の UIView サブクラスを呼び出します。

Stars.h

@interface Stars : UIView {

    BOOL _gained;

}

@property (nonatomic, weak) id<NSObject> delegate;
@property (nonatomic) BOOL gained;

-(void)animateAndRemove;

@end

スターズ.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;
}

現在、クラスが removedFromSuperview で nil に設定されている場合、dealloc の NSLog は呼び出されません。なぜだめですか?

この Stars クラスをロードしている最初の UIView で実際に同じことを見ています。それも、私がそうすべきだと思うときに解放していません。含まれている UIView を alloc して再度初期化することで再割り当てすると、両方の dealloc メソッドがそのまま呼び出されます。

ビューから削除されてnilに設定されたときに、これが解放されると期待するのは間違っていますか?

4

1 に答える 1

1

あなたを考慮してくださいremoveStar

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

これは、次の行に沿った呼び出しを使用して、どこかから呼び出す必要があります。

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

現在、変数starinremoveStarはそのメソッドに対してローカルです。メソッドが呼び出されると、この変数は渡されたStars参照に初期化されるため、追加の参照があります。removeStar呼び出し元が持っている参照に加えてStars、メソッドが呼び出されたインスタンスへ。

nil次に、このローカル変数に割り当てると、この追加の参照のみが削除されます。の呼び出し元にはremoveStarまだその参照があります。いいえdealloc

推測: の呼び出し元removeStarはおそらくインスタンスの所有者であり、その参照も削除する必要があります。

于 2012-06-09T19:45:28.653 に答える