关闭后UIView消失并重新打开应用程序[自定义UIView类别]

时间:2014-07-17 01:04:20

标签: ios objective-c uiview drawrect

我创建了一个UIView类,可以轻松绘制而无需创建UIView的子类。 问题是,当我关闭应用程序并重新打开时(通常在低内存条件下),UIView绘图消失了。

我向您展示了该类别的代码:

的UIView + DrawBlock.h

#import <UIKit/UIKit.h>

// Blocks
typedef void(^DrawBlock)(CGContextRef context, CGRect drawFrame);
typedef void(^CompletionBlock)(UIView *view);

@interface UIView (DrawBlock)

- (void)drawInside:(DrawBlock)block withResult:(CompletionBlock)completion;

@end

的UIView + DrawBlock.m

#import "UIView+DrawBlock.h"

#pragma mark - Auxiliar UIView
@interface DrawingView : UIView
@property (strong, nonatomic) DrawBlock drawBlock;
- (void)setDrawRectBlock:(DrawBlock)block;
@end

@implementation DrawingView
- (void)setDrawRectBlock:(DrawBlock)block {
    _drawBlock = block;
    if (_drawBlock) {
        [self setNeedsDisplay];
    }
}
- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    if (_drawBlock) {
        _drawBlock(context, rect);
        _drawBlock = nil;
    }

}
@end

#pragma mark - Category
@implementation UIView (DrawBlock)
- (void)drawInside:(DrawBlock)block withResult:(CompletionBlock)completion {
    if (block) {
        DrawingView *drawView = [[DrawingView alloc] init];
        drawView.translatesAutoresizingMaskIntoConstraints = NO;
        drawView.userInteractionEnabled = NO;
        drawView.backgroundColor = [UIColor clearColor];
        [self addSubview:drawView];

        NSDictionary *views = NSDictionaryOfVariableBindings(drawView);
        NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[drawView]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views];
        [self addConstraints:constraints];
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[drawView]|"
                                                              options:0
                                                              metrics:nil
                                                                views:views];
        [self addConstraints:constraints];
        [drawView setDrawRectBlock:block];

        if (completion != nil) {
            completion(drawView);
        }
    }
}

@end

我认为问题出在代码的这一部分:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    if (_drawBlock) {
        _drawBlock(context, rect);
        _drawBlock = nil;
    }

}

如果我评论这一行:

_drawBlock = nil;
似乎一切正常,但内存消耗不会停止而且应用变得非常慢。

有什么想法吗?子类不是一个选项。

谢谢!

更新1 使用示例

- (void)drawOnView {

    [self.view drawInside:^(CGContextRef context, CGRect drawFrame) {

        // Oblique lines
        CGMutablePathRef obliquePath = CGPathCreateMutable();
        CGFloat height = CGRectGetHeight(drawFrame);
        for (CGFloat x = -height; x < CGRectGetWidth(drawFrame); x += 7.5) {
            CGPathMoveToPoint(obliquePath, nil, x, 0.0);
            CGPathAddLineToPoint(obliquePath, nil, x + height, height);
        }
        CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:0.0 alpha:0.04].CGColor);
        CGContextSetLineWidth(context, 2.0);
        CGContextAddPath(context, obliquePath);
        CGContextStrokePath(context);
        CGPathRelease(obliquePath);


    } withResult:^(UIView *view) {

        [self.view sendSubviewToBack:view];

    }];

}

enter image description here

1 个答案:

答案 0 :(得分:0)

首先,应该复制块,而不是保留块。在strong属性声明中将copy替换为drawBlock

接下来,你是对的,你不应该阻止阻止,因为DrawingView drawRect:需要重新显示。

内存问题可能是保留周期。确保你不会从街区内进入自己,也不会进入伊娃。

之后弱化自我之外的自我
__weak typeof(self) weakSelf = self;


[self drawInside:^{
    // use only weakSelf 
} ...

如果这对您的块显示drawInside:调用示例没有帮助。另外,你从哪里来称呼它?


最后,假设DrawingView采用其完整的超视图大小,单个DrawingView可以更有效地将绘制块存储在内部数组中,并从单个{{{ 1}}打电话。为每个块创建一个新的drawRect,根本没有约束,似乎有点开销。

但这更为先进,我建议你先把基本案例搞定。