ios - 如何在其 subview 之一正在动画时释放 UIView?

标签 ios objective-c cocoa-touch uiview memory-leaks

enter image description here ------> enter image description here

我正在尝试创建自定义 UIActivityIndicatorView .自定义 View 的行为应该与标准 View 完全相同,除了它旋转的图像看起来不同。我注意到在以下测试代码中,当我的自定义 View 从其 super View 中删除时,它不会被释放:

ActivityIndicatorCustomView* v = [[ActivityIndicatorCustomView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 100.0f, 100.0f)];
[[UIApplication sharedApplication].keyWindow addSubview:v];
[v removeFromSuperview];

罪魁祸首是动画 block ,因为当它被注释掉时,会调用dealloc。我相信这是一个保留周期,但我不知道如何解决这个问题。

ActivityIndi​​catorCustomView.h

#import <UIKit/UIKit.h>

@interface ActivityIndicatorCustomView : UIView

@property(nonatomic, assign, readonly) BOOL isAnimating;

- (void)startAnimating;
- (void)stopAnimating;

@end

ActivityIndi​​catorCustomView.m

static const NSTimeInterval ANIMATION_PERIOD_HALF_LIFE = 1.0f;

#import "ActivityIndicatorCustomView.h"

@interface ActivityIndicatorCustomView ()

@property(nonatomic, strong) UIImageView* imageView;
@property(nonatomic, assign, readwrite) BOOL isAnimating;

- (void)animateWithTransform:(CGAffineTransform)transform;

@end

@implementation ActivityIndicatorCustomView

#pragma mark NSObject

- (void)dealloc
{
    NSLog(@"dealloc");
}

#pragma mark UIView

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"activityIndicatorCustom"]];
        self.imageView.frame = self.bounds;
        [self addSubview:self.imageView];
    }

    return self;
}

- (void)didMoveToSuperview
{
    if (!self.hidden && self.superview != nil) {
        [self startAnimating];
    }
}

- (void)willMoveToSuperview:(UIView *)newSuperview
{    
    if (newSuperview == nil) {
        [self stopAnimating];
    }
}

- (void)setHidden:(BOOL)hidden
{
    if (hidden) {
        [self stopAnimating];
    } else if (self.superview != nil) {
        [self startAnimating];
    }

    [super setHidden:hidden];
}

#pragma mark ActivityIndicatorCustomView 

- (void)startAnimating
{
    if (self.isAnimating) {
        return;
    }

    self.isAnimating = YES;
    [self animateWithTransform:CGAffineTransformMakeRotation((CGFloat)M_PI)];
}

- (void)stopAnimating
{
    [self.imageView.layer removeAllAnimations];
    self.isAnimating = NO;
}

#pragma mark ()

- (void)animateWithTransform:(CGAffineTransform)transform
{
    // Must split the animation into two semi-circles. If 
    // you attempt to rotate a full circle, nothing will
    // happen.
    __block ActivityIndicatorCustomView* weakSelf = self;

    [UIView
        animateWithDuration:ANIMATION_PERIOD_HALF_LIFE
        delay:0.0
        options:UIViewAnimationOptionCurveLinear
        animations:^{
            weakSelf.imageView.transform = transform;
        } completion:^(BOOL finished) {
            [weakSelf animateWithTransform:CGAffineTransformIsIdentity(transform)
                ? CGAffineTransformMakeRotation((CGFloat)M_PI)
                : CGAffineTransformIdentity
            ];
        }
    ];
}

@end

最佳答案

我正在关注 bad tutorial在 block 中保留循环。它告诉我要做

__block MyViewController *weakSelf = self;

这是错误的。要创建弱引用,我应该这样做:

__weak ActivityIndicatorCustomView* weakSelf = self;

[UIView
    animateWithDuration:ANIMATION_PERIOD_HALF_LIFE
    delay:0.0
    options:UIViewAnimationOptionCurveLinear
    animations:^{
        weakSelf.imageView.transform = transform;
    } completion:^(BOOL finished) {
        [weakSelf animateWithTransform:CGAffineTransformIsIdentity(transform)
            ? CGAffineTransformMakeRotation((CGFloat)M_PI)
            : CGAffineTransformIdentity
        ];
    }
];

关于ios - 如何在其 subview 之一正在动画时释放 UIView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27431483/

相关文章:

iphone - iOS 可点击词(UILabel 或 UIbutton 的)

ios - ionic 应用程序不会登录 Xcode

objective-c - iOS调出WiFi认证表

ios - 在 box2d 中添加 Sprite 到固定装置

ios - 如何在 iOS 中的 xib 中设置十六进制颜色代码

ios - Xcode 与 iPhone 失去连接

objective-c - Objective c NSURL 可能不会响应 +initFileURLWithPath

ios - Objective-C Game Center自动匹配“由于与服务器通信出错,无法完成请求的操作。”

iphone - 使用 SDURLCache(NSURLCache 的子类)时的内存泄漏

iphone - UIWebView 在横向 View 右侧加载一些黑屏