我有一个UIView
子类,可以操作多个层。因为视图的图层sublayers
强烈保留了图层,我的想法是让我自己对它们的引用很弱:
@interface AnchorCell : UICollectionReusableView
@property (weak, nonatomic) CAShapeLayer *link;
@property (weak, nonatomic) CATextLayer *offset;
@end
我可以在初始时进行一定数量的设置。但我最终编写了这样的代码:
- (void) initLink {
CAShapeLayer *shape = _link = [CAShapeLayer layer]; // have to put it in local variable to make it last long enough to get to the sublayer
_link.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent: 1].CGColor;
_link.fillColor = nil;
_link.lineWidth = 3;
_link.masksToBounds = NO;
....
[self.layer addSublayer: _link];
}
我很好奇是否有更好的习惯方式来做到这一点。关于上述内容我喜欢的是,它尽可能地突出显示我设置了link
变量,而不是一些本地shape
变量,然后我在最后设置为link
。我不喜欢的是你必须添加一个局部变量,因为Xcode没有明确的警告。
我可以将addSublayer:
移到方法的顶部:
- (void) initLink {
CAShapeLayer *shape = [CAShapeLayer layer];
[self.layer addSublayer: shape];
_link = shape;
_link.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent: 1].CGColor;
_link.fillColor = nil;
_link.lineWidth = 3;
_link.masksToBounds = NO;
}
但这也隐藏了(对我来说)。它并没有明确表示已将link
添加为子图层。此外,有时,在在其他地方注册之前,您必须对该对象进行一定程度的设置。
有更优雅的方式吗?或者至少有一种更为惯用的方式,考虑到ARC管理的ObjectiveC的限制?
答案 0 :(得分:4)
我认为您不应该仅仅为了避免使用局部变量来创建属性strong
(如果属性为weak
,则需要局部变量)。
我认为内存语义(例如weak
vs strong
vs copy
)应该反映功能对象所有权图,而不是为了避免使用局部变量。我会将该属性保留为weak
,然后执行明显的操作:
CAShapeLayer *shape = [CAShapeLayer layer]; // have to put it in local variable to make it last long enough to get to the sublayer
shape.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent: 1].CGColor;
shape.fillColor = nil;
shape.lineWidth = 3;
shape.masksToBounds = NO;
....
[self.layer addSublayer: shape];
self.link = shape;
就我个人而言,我不认为在一行代码中分配shape
和_link
的行提高了它的可读性,所以我更喜欢将它们分开,但是做任何你想做的事情。
此外,我通常建议使用setter,因为我永远不知道我是否可能有一个自定义setter或在将来某个日期更改内存语义(这里的代码不应该关注它)。不止一次,我不得不重构直接使用ivar的代码,因为一些实现细节在以后发生了变化,但我还没有后悔使用访问器方法。
答案 1 :(得分:1)
您可能需要尝试代码块评估,如this blog post。
中所述像:
_link = ({
CAShapeLayer *shape = [CAShapeLayer layer];
shape.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent: 1].CGColor;
shape.fillColor = nil;
shape.lineWidth = 3;
shape.masksToBounds = NO;
[self.layer addSublayer: shape];
shape;
)};
答案 2 :(得分:0)
我认为你根本不需要临时变量形状 - 只需:
_link = [CAShapeLayer layer];
或
self.link = [CAShapeLayer layer];
请注意,如果你成为子图层后再也不需要_link那么你可以使用局部变量完成所有操作并跳过@property。
希望这有帮助。