Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/122.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CAShapeLayer内存管理难题_Ios_Memory Management_Uiview_Automatic Ref Counting_Calayer - Fatal编程技术网

Ios CAShapeLayer内存管理难题

Ios CAShapeLayer内存管理难题,ios,memory-management,uiview,automatic-ref-counting,calayer,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 moveToPo

我的
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];
}
strong属性

@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;
令人困惑的是,这三个中的两个导致了三角形的出现。局部变量有,弱属性没有,但强属性有。起初,我只是玩了一下属性,得出结论认为
addSublayer:
必须是
弱连接,所以我需要
strong
引用它。但如果是这样,那么为什么局部变量版本可以工作呢。我很困惑


(是的,我知道三角形不太像水龙头)

您可以在创建属性时立即将
CAShapeLayer
分配给属性。因此,如果属性较弱,则会立即解除分配,因为它没有对它的强引用。您可以在方法中将其分配给局部变量,这样在方法中可以保持对它的强引用。然后,一旦你添加它作为一个子层,它将有一个强大的参考那里,你的财产可能会很弱,没有得到解除分配

编辑:

进一步澄清。。。因此,下面一行:

self.faucet = [CAShapeLayer layer];
结果将创建
CAShapeLayer
,将其分配给弱属性,然后立即解除分配(因为它没有强引用),并导致弱属性设置为nil(因为弱指针就是这样工作的)。它基本上与该行相同:

[CAShapeLayer layer];
您可以改为执行以下操作以使属性保持弱:

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

局部变量在其范围内时保持强引用。

有意义。我做出了错误的假设,认为方法的作用域会保持它的存在,但那是因为我试图将该属性视为局部变量太多了。了解
弱属性的有用经验。这就是弱属性的危险。如果编译器足够聪明,能够警告这种情况就好了。但至少在大多数情况下,事情显然出了问题。