0

我在我的UIView子类中有以下代码的三种变体。CAShapeLayer内存管理窘境

局部变量

- (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引用它。但是,如果是这种情况,那么为什么本地变量版本工作。我很困惑。

是的,我知道一个三角形是没有太大的龙头)的

回答

1

你开始通过立即在创建它分配CAShapeLayer的财产。所以如果这个属性很弱,那么它会立即释放,因为它没有强烈的引用。您可以将它分配给方法中的局部变量,这将在方法中保留强引用。然后,一旦你将它作为一个子层添加,它将在那里有一个强有力的参考,并且你的财产可以很弱,而不会被释放。

编辑:

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

self.faucet = [CAShapeLayer layer]; 

导致CAShapeLayer创建,分配给弱属性,那么之后(因为它没有立即释放强引用),并导致弱属性设置为零(因为这是指针工作的弱点)。这是该行基本相同:

[CAShapeLayer layer]; 

你可以改为执行以下操作,以保持性能弱:

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

局部变量保持很强的借鉴意义,而它仍然在范围内。

+0

有道理。我做了一个错误的假设,即该方法的范围会使它保持活跃,但那是因为我试图将该属性视为局部变量太多。理解“弱”属性的有用经验。 –

+0

这是弱财产的危险。如果只有编译器足够聪明才能警告这种情况。但至少在大多数情况下,显然有些事情是错误的。 – Gavin