CAShapeLayer内存管理窘境

时间:2014-01-14 18:22:27

标签: ios memory-management uiview automatic-ref-counting calayer

我的UIView子类中有以下代码的三种变体。

本地变量

- (void)setupLayer {
    CAShapeLayer *faucet = [CAShapeLayer layer];
    faucet.strokeColor = [[UIColor blackColor] CGColor];
    faucet.lineWidth = 1;
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint: CGPointMake(0, 0)];
    [path addLineToPoint: CGPointMake(50, 0)];
    [path addLineToPoint: CGPointMake(0, 50)];
    [path closePath];
    faucet.path = [path CGPath];
    [self.layer addSublayer: faucet];
}

弱财产

@interface ValveStatusView : UIView
@property (weak, nonatomic) CAShapeLayer *faucet;
@end
@implementation ValveStatusView
- (void)setupLayer {
    self.faucet = [CAShapeLayer layer];
    self.faucet.strokeColor = [[UIColor blackColor] CGColor];
    self.faucet.lineWidth = 1;
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint: CGPointMake(0, 0)];
    [path addLineToPoint: CGPointMake(50, 0)];
    [path addLineToPoint: CGPointMake(0, 50)];
    [path closePath];
    self.faucet.path = [path CGPath];
    [self.layer addSublayer: self.faucet];
}

强势属性

与上述相同,但是:

    @property (strong, nonatomic) CAShapeLayer *faucet;

窘境是这3个中的2个导致三角形出现。 本地变量弱属性没有,但强属性。刚开始我只使用了属性,并断定addSublayer:必须是weak连接,所以我需要strong引用它。但如果是这种情况,那么为什么 Local Variable 版本可行。我很困惑。

是的,我知道一个三角形不是一个水龙头

1 个答案:

答案 0 :(得分:1)

首先,在创建属性后立即将CAShapeLayer分配给属性。因此,如果属性很弱,那么它会被立即释放,因为它没有强引用。您可以将其分配给方法中的局部变量,这将在方法中保留对它的强引用。然后,一旦你将它作为子图层添加,它就会有一个强大的引用,并且你的属性可能很弱,而不会被解除分配。

编辑:

进一步澄清......所以,以下一行:

self.faucet = [CAShapeLayer layer];

导致创建CAShapeLayer,分配给弱属性,然后立即解除分配(因为它没有强引用)并导致弱属性设置为nil(因为这是弱指针的工作方式) 。它基本上与行相同:

[CAShapeLayer layer];

您可以改为执行以下操作以使属性保持弱势:

CAShapeLayer *faucet = [CAShapeLayer layer];
self.faucet = faucet;

局部变量在仍在范围内时保留强引用。