简体   繁体   English

CGImageRef属性保留或不保留

[英]CGImageRef property retain or not retain

I have a question on how to handle a CGImageRef as a synthesized property of a class. 我有一个关于如何处理CGImageRef作为类的综合属性的问题。 If I define an CGImageRef with 如果我定义CGImageRef

@property (nonatomic, retain) CGImageRef image;

then the compiler complains that "retain" cannot be used here. 然后编译器抱怨这里不能使用“retain”。 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: 如果我省略保留,那么我假设使用“assign”,我需要在设置属性时自行保留:

self.image = CGImageRetain ( cgimage );

then I get an "Potential leak" warning when running Analyze. 然后我在运行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? 或者,即使在属性定义中没有指定“retain”,合成代码仍会执行隐式CGRetain吗?

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. 请注意,这只会为您生成getter和setter,实例变量本身不受 ARC控制。 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. 具体来说,这意味着您必须在dealloc释放它,并且在直接分配给实例变量时需要使用正确的保留和释放。


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 . __attribute__((NSObject))应用于不属于可保留对象指针类型的属性具有与ARC之外相同的行为:它要求属性类型为某种指针并允许使用除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. 对ivar的直接访问(即使合成)仍然具有原始语义,并且在重新分配期间不会自动释放ivar中的值。

and section 3 : 第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) 块指针(通过将插入符号( ^ )声明符sigil应用于函数类型而形成)
  • Objective-C object pointers ( id , Class , NSFoo* , etc.) Objective-C对象指针( idClassNSFoo*等)
  • typedefs marked with __attribute__((NSObject)) typedef标有__attribute__((NSObject))

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

How about this? 这个怎么样?

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM