CGImageRef财产保留或不保留

时间:2022-09-07 10:54:41

I have a question on how to handle a CGImageRef as a synthesized property of a class. If I define an CGImageRef with

我有一个问题,关于如何将CGImageRef作为类的合成属性来处理。如果我用CGImageRef定义

@property (nonatomic, retain) CGImageRef image;

then the compiler complains that "retain" cannot be used here. If I leave out the retain, then I assume "assign" is used instead, and I need to do the retain myself when I set the property:

然后编译器会抱怨“retain”不能在这里使用。如果我省略了retain,那么我假设用的是assign,我在设置属性时需要自己做retain:

self.image = CGImageRetain ( cgimage );

then I get an "Potential leak" warning when running Analyze. Can I safely ignore this warning? Or does the synthesize code do an implicit CGRetain anyways, even though no "retain" is specified in the property definition?

然后在运行分析时,会得到一个“潜在泄漏”警告。我能安全地忽略这个警告吗?或者,合成代码是否做隐式的CGRetain,即使在属性定义中没有指定“retain”?

3 个解决方案

#1


8  

What you want to do is add an annotation to the property that the type really can be retained.

您需要做的是向属性添加一个注释,该类型实际上可以保留。

Change the property declaration to

将属性声明更改为

@property (nonatomic, retain) CGImageRef image __attribute__((NSObject));

Note that this will only generate the getters and setters for you, the instance variable itself is not ARC controlled. Specifically, this means that you must release it in dealloc, and that you need to use proper retain and release when assigning directly to the instance variable.

注意,这只会为您生成getter和setter,实例变量本身不受ARC控制。具体地说,这意味着必须在dealloc中释放它,并且在直接分配实例变量时需要使用适当的retain和release。


A better approach may be to use a typedef:

更好的方法可能是使用typedef:

typedef CGImageRef CGImageObject __attribute__((NSObject));
@property (nonatomic, retain) CGImageObject image;

In this case, the instance variable is controlled by ARC, and so you must not release it in dealloc, and direct assignments to the instance variable are handled by ARC as well.

在这种情况下,实例变量由ARC控制,因此不能在dealloc中释放它,并且对实例变量的直接赋值也由ARC处理。


For reference, see the specification, specifically section 4.1.1:

请参阅规范,特别是第4.1.1节:

Applying __attribute__((NSObject)) to a property not of retainable object pointer type has the same behavior it does outside of ARC: it requires the property type to be some sort of pointer and permits the use of modifiers other than assign. These modifiers only affect the synthesized getter and setter; direct accesses to the ivar (even if synthesized) still have primitive semantics, and the value in the ivar will not be automatically released during deallocation.

对不属于可保存对象指针类型的属性应用__attribute__((NSObject)),其行为与在ARC之外的行为相同:它要求属性类型是某种类型的指针,并允许使用除赋值之外的修饰符。这些修饰符只影响合成的getter和setter;对ivar的直接访问(即使是合成的)仍然具有原始语义,并且在释放时不会自动释放ivar中的值。

and section 3:

第三节:

A retainable object pointer (or “retainable pointer”) is a value of a retainable object pointer type (“retainable type”). There are three kinds of retainable object pointer types:

可保留的对象指针(或“可保留指针”)是可保留对象指针类型的值(“可保存类型”)。有三种可保留的对象指针类型:

  • block pointers (formed by applying the caret (^) declarator sigil to a function type)
  • 块指针(由应用插入符号(^)说明符魔符函数类型)
  • Objective-C object pointers (id, Class, NSFoo*, etc.)
  • Objective-C对象指针(id、类、NSFoo*等)
  • typedefs marked with __attribute__((NSObject))
  • typedef标有__attribute__((NSObject))

#2


1  

I don't like to instruct the compiler when compiling. I think it's ugly. I'd override the methods myself.

我不喜欢在编译时指导编译器。我认为这是丑陋的。我会自己重写这些方法。

@interface MyClass : NSObject {
    CGImageRef _image;
}
@property (nonatomic, assign) CGImageRef image;
@end

@implementation MyClass
- (void)setImage:(CGImageRef)i {
    if(_image != i) {
        CGImageRelease(_image);
        _image = CGImageRetain(i);
    }
}

- (CGImageRef)image {
    return _image;
}
@end

#3


-1  

How about this?

这个怎么样?

@property (nonatomic, setter=setImage:) CGImageRef image;

(void)setImage:(CGImageRef)image {
    if (_image != image) {
        CGImageRelease(_image);
        _image = CGImageRetain(image);
    }
}

#1


8  

What you want to do is add an annotation to the property that the type really can be retained.

您需要做的是向属性添加一个注释,该类型实际上可以保留。

Change the property declaration to

将属性声明更改为

@property (nonatomic, retain) CGImageRef image __attribute__((NSObject));

Note that this will only generate the getters and setters for you, the instance variable itself is not ARC controlled. Specifically, this means that you must release it in dealloc, and that you need to use proper retain and release when assigning directly to the instance variable.

注意,这只会为您生成getter和setter,实例变量本身不受ARC控制。具体地说,这意味着必须在dealloc中释放它,并且在直接分配实例变量时需要使用适当的retain和release。


A better approach may be to use a typedef:

更好的方法可能是使用typedef:

typedef CGImageRef CGImageObject __attribute__((NSObject));
@property (nonatomic, retain) CGImageObject image;

In this case, the instance variable is controlled by ARC, and so you must not release it in dealloc, and direct assignments to the instance variable are handled by ARC as well.

在这种情况下,实例变量由ARC控制,因此不能在dealloc中释放它,并且对实例变量的直接赋值也由ARC处理。


For reference, see the specification, specifically section 4.1.1:

请参阅规范,特别是第4.1.1节:

Applying __attribute__((NSObject)) to a property not of retainable object pointer type has the same behavior it does outside of ARC: it requires the property type to be some sort of pointer and permits the use of modifiers other than assign. These modifiers only affect the synthesized getter and setter; direct accesses to the ivar (even if synthesized) still have primitive semantics, and the value in the ivar will not be automatically released during deallocation.

对不属于可保存对象指针类型的属性应用__attribute__((NSObject)),其行为与在ARC之外的行为相同:它要求属性类型是某种类型的指针,并允许使用除赋值之外的修饰符。这些修饰符只影响合成的getter和setter;对ivar的直接访问(即使是合成的)仍然具有原始语义,并且在释放时不会自动释放ivar中的值。

and section 3:

第三节:

A retainable object pointer (or “retainable pointer”) is a value of a retainable object pointer type (“retainable type”). There are three kinds of retainable object pointer types:

可保留的对象指针(或“可保留指针”)是可保留对象指针类型的值(“可保存类型”)。有三种可保留的对象指针类型:

  • block pointers (formed by applying the caret (^) declarator sigil to a function type)
  • 块指针(由应用插入符号(^)说明符魔符函数类型)
  • Objective-C object pointers (id, Class, NSFoo*, etc.)
  • Objective-C对象指针(id、类、NSFoo*等)
  • typedefs marked with __attribute__((NSObject))
  • typedef标有__attribute__((NSObject))

#2


1  

I don't like to instruct the compiler when compiling. I think it's ugly. I'd override the methods myself.

我不喜欢在编译时指导编译器。我认为这是丑陋的。我会自己重写这些方法。

@interface MyClass : NSObject {
    CGImageRef _image;
}
@property (nonatomic, assign) CGImageRef image;
@end

@implementation MyClass
- (void)setImage:(CGImageRef)i {
    if(_image != i) {
        CGImageRelease(_image);
        _image = CGImageRetain(i);
    }
}

- (CGImageRef)image {
    return _image;
}
@end

#3


-1  

How about this?

这个怎么样?

@property (nonatomic, setter=setImage:) CGImageRef image;

(void)setImage:(CGImageRef)image {
    if (_image != image) {
        CGImageRelease(_image);
        _image = CGImageRetain(image);
    }
}