0

나는 UIView 하위 클래스가 있으며,이 내에서이 다른 UIView 하위 클래스를 호출합니다.ARC를 사용할 때 클래스 dealloc이 호출되지 않는 이유는 무엇입니까?

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 

이 단순히 내가 제거하기 전에 애니메이션 이미지를 추가합니다. 이 같은 애니메이션을 제거 프로세스를

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

을 그리고 시작 : I는 다음과 같이 원래의 UIView이 추가

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는 클래스가 removedFromSuperview이고 nil로 설정된 경우 호출되지 않습니다. 왜 안돼?

저는이 Stars 클래스를로드하고있는 첫 번째 UIView에서 실제로 같은 것을 보았습니다. 그것도 제가 생각할 때 탈퇴하지 않습니다. 두 dealloc 메서드는 alloc에 ​​의해 UIView를 재 할당하고 다시 초기화 할 때 그대로 호출됩니다.

뷰에서 제거되어 nil로 설정되면 dealloc이 필요하다고 잘못 생각합니까?

+0

참조로 참조가 아닌 참조 참조를 전달하고 있기 때문에 그 이유가 있습니다. –

+0

조금 더 자세히 설명해 주시겠습니까? 나는 당신이 의미하는 것을 이해하지 못합니다. 감사합니다 – Darren

답변

1

고려하여 removeStar :

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

이이 곳의 라인을 따라 전화를 사용하여 호출해야합니다

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

지금 removeStar에서 변수 star 그 방법 지역입니다. 메소드가 호출 될 때이 변수는 Stars 참조로 전달되도록 초기화됩니다. 따라서 참조가 추가됩니다. 참조 번호 이상인 removeStar에는 Stars 인스턴스에 메소드가 호출됩니다.

로컬 변수에 할당하면이 추가 참조 만 제거됩니다. removeStar의 호출자는 여전히 참조를 가지고 있습니다. 따라서 no dealloc.

추측 : removeStar의 발신자는 인스턴스의 소유자 일 가능성이 높기 때문에 해당 참조도 제거해야합니다.

+0

애니메이션이 완료된 후 StarStar 클래스에서 removeStar를 호출하고 보낸 사람으로 자신을 전달하는 것을 볼 수 있습니다. 나는 포인터가 어디에 있든간에, 하나를 nil로 설정하면 객체를 nil로 설정한다고 가정했다. 감사 – Darren

관련 문제