I have three variants of the following code in my UIView
subclass.
Local Variable
- (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];
}
Weak Property
@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 Property
Same as above except:
@property (strong, nonatomic) CAShapeLayer *faucet;
The quandary is that 2 of those 3 cause the triangle to show up. The Local Variable does, the Weak Property does NOT, but the Strong Property does. At first I just played with the properties, and concluded that addSublayer:
must be a weak
connection, so I needed have the strong
reference to it. But if that was the case, then why does the Local Variable version work. I'm confused.
(and yes, I know a triangle's not much of a faucet)
You start by assigning the CAShapeLayer
to the property immediately upon creating it. So if the property is weak, then it is immediately deallocated because it has no strong references to it. You could assign it to a local variable in the method, which would keep a strong reference to it while in the method. Then once you add it as a sublayer, it will have a strong reference there, and your property can be weak without it getting deallocated.
EDIT:
Further clarification... So, the following line:
self.faucet = [CAShapeLayer layer];
results in the CAShapeLayer
being created, assigned to a weak property, then deallocated immediately after (because it has no strong references) and results in the weak property getting set to nil (because that's how weak pointers work). It is essentially identical to the line:
[CAShapeLayer layer];
You could instead do the following to keep the property weak:
CAShapeLayer *faucet = [CAShapeLayer layer];
self.faucet = faucet;
The local variable keeps a strong reference while it's still in scope.