如果在初始化程序中创建,则会立即释放对象,但如果在方法中创建则不会

时间:2014-05-30 09:37:11

标签: ios objective-c memory-management

我有以下课程:

@implementation MyUICollectionViewCell {
    CAShapeLayer *layr;
}


- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.layer.mask = [CAShapeLayer layer];
        layr = [CAShapeLayer layer];
    }
    return self;
}

- (void)initMask {
    self.layer.mask = [CAShapeLayer layer];
}

- (void)updateMask {   
    CAShapeLayer *maskLayer = (CAShapeLayer*) self.layer.mask;
    maskLayer.frame = ...;
    maskLayer.path = ...;
}

@end

如果我在构造函数中指定self.layer.mask,则nil方法中的updateMaskinitMask。但是,如果在layr方法中完成赋值(从类外部调用),则一切正常。

有人能解释一下这里发生了什么吗?


修改 尝试将对象存储在ivar中(即nil),但无效 - 它仍然是updateMask中的{{1}}。

4 个答案:

答案 0 :(得分:5)

我认为在调用initWithFrame时尚未启动图层内容。这将导致覆盖您稍后在初始化期间设置的图层信息。

我前段时间使用的是layoutSubViews的覆盖。在您的情况下,这将类似于以下内容:

-(void)layoutSubViews
{
    [super layoutSubviews];  // Added due to remark below

    self.layer.mask = [CAShapeLayer layer];
}

我希望这会给你一个替代方案。

答案 1 :(得分:2)

Practical Memory Management文档中,Apple建议“不要在初始化方法中使用访问器方法... ”,因为正在初始化的对象可能处于半初始化状态。 this blog中解释了相同的内容 所以我认为您不应该使用语句self.layer.mask = [CAShapeLayer layer];,而是直接访问iVars

答案 2 :(得分:0)

而不是initWithFrameinit方法

中执行此操作
-(id)init
{
  if (self = [super init])
  {
    self.layer.mask = [CAShapeLayer layer];
  }
}

答案 3 :(得分:0)

尝试在viewDidLoad中执行此操作。 在init部分中,您需要处理parroters初始化,但视图中的可视内容仅在加载后才会加载。

或覆盖   - (无效)layoutSubViews