保留核心基础财产

发布于 2025-01-05 07:03:49 字数 762 浏览 5 评论 0原文

(Xcode 4.2、iOS 5、ARC

我有 Core Foundation (/Graphics) 对象的一些属性,这些属性应该取得其对象的所有权。现在在这些 Apple 文档 我发现了这个:

在 OS X v10.6 及更高版本中,您可以使用 __attribute__ 关键字来指定 Core Foundation 属性应被视为 用于内存管理的 Objective-C 对象: @property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

不幸的是,我找不到对此的任何详细说明。我正在使用这个:

@property (nonatomic, Strong) __attribute__((NSObject)) CGImageRef loupeImage;

它似乎按照我期望的方式工作。它在设置属性时保留对象,并在我将属性设置为零时释放它。

现在我的问题是,我是否仍然需要在我的 dealloc 中显式地将这些属性设置为 nil ?

(Xcode 4.2, iOS 5, ARC)

I have some properties of Core Foundation (/Graphics) objects that should take ownership of their objects. Now in these Apple docs I found this:

In OS X v10.6 and later, you can use the __attribute__ keyword to specify that a Core Foundation property should be treated like an
Objective-C object for memory management:
@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Unfortunately I couldn't find any elaboration on this. I'm using this:

@property (nonatomic, strong) __attribute__((NSObject)) CGImageRef loupeImage;

And it seems to work the way I'd expect. It retains the object on setting the property and releases it when I set the property to nil.

Now my question is, do I still need to explicitly set those properties to nil in my dealloc?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

微凉徒眸意 2025-01-12 07:03:49

编辑:我之前的帖子不正确。属性上的 __attribute__((NSObject)) 仅导致它在使用属性访问器时保留/释放该属性。它不会影响对 ivar 的访问,值得注意的是,它不会清空(或释放)dealloc 中的属性。所以是的,在你的dealloc中你要么需要说self.loupeImage = nil;要么你需要说[_loupeImagerelease]。


原始帖子

如果编译器接受 strong 关键字,那么它将正确对待它,按预期保留和释放,并在 ARC 中自动清空。 __attribute__((NSObject)) 的整个想法是它告诉编译器将该对象完全视为 obj-c 对象,这就是它的作用。

所以不,你不必在 dealloc 中显式地将它们清零。您将获得自动清空/释放的默认 ARC 行为。

Edit: My previous post was incorrect. __attribute__((NSObject)) on the property only causes it to retain/release the property when using the property accessors. It does not affect access to the ivar, and notably, it does not nil out (or release) the property in dealloc. So yes, in your dealloc you either need to say self.loupeImage = nil; or you need to say [_loupeImage release].


Original post:

If the compiler accepts the strong keyword, then it's going to treat it correctly, retaining and releasing as expected, and nilling out automatically in ARC. The whole idea of __attribute__((NSObject)) is it tells the compiler to treat this object exactly as if it were an obj-c object, and so that's what it does.

So no, you shouldn't have to explicitly nil them out in dealloc. You'll get the default ARC behavior of nilling/releasing automatically.

野の 2025-01-12 07:03:49

现在我的问题是,我是否还需要显式设置这些属性
在我的 dealloc 中为零?

是的,您确实如此,并附有您出示的声明。

在 ARC 规范的属性声明部分中,它说:

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

(强调我添加的最后一部分)

换句话说,在具有 Core Foundation 类型的属性上应用 __attribute__((NSObject)) 和 strong 可以使 getter 和 setter 正常工作,但它不会让 ARC 管理底层实例变量(因为实例变量的类型仍然是 Core Foundation 类型),因此如果实例变量是非类型,ARC 不会在 dealloc 时释放该实例变量。零。对于这样的属性声明,您必须在dealloc中将其清零,否则会导致泄漏。

然而,有一种方法可以让 ARC 自己管理变量。由于该变量具有 Core Foundation 类型,因此您可以通过使用 __attribute__((NSObject)) 将其包装在 typedef 中,使其成为 ARC 管理的类型。

ARC 规范的 可保留对象指针部分表示:

可保留对象指针类型共有三种:

  • 块指针(通过应用脱字符号 (^) 声明符形成
    函数类型的印记)
  • Objective-C 对象指针(idClassNSFoo* 等)
  • __attribute__((NSObject)) 标记的 typedef

(强调我添加的最后一项)

因此,如果您创建这样的 typedef:

typedef __attribute__((NSObject)) CGImageRef MyImageRef;

并声明您的属性,如下所示:

@property (nonatomic, strong) MyImageRef loupeImage;

底层变量将由 ARC 管理(因为基础变量将具有typedef 的类型,这是 ARC 管理的类型),并且您不必在 dealloc 中将其置零。

Now my question is, do I still need to explicitly set those properties
to nil in my dealloc?

Yes, you do, with the declaration you showed.

In the Property declarations section of the ARC specification, it says:

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
.

(emphasis on last part added by me)

In other words, applying __attribute__((NSObject)) and strong on a property with Core Foundation type makes the getters and setters work correctly, but it will not make ARC manage the underlying instance variable (because the instance variable's type will still be the Core Foundation type), and thus ARC will not release the instance variable upon dealloc if it is non-nil. With such a property declaration, you will have to nil it in dealloc or cause a leak.

However, there is a way to make ARC manage the variable itself. Since the variable has a Core Foundation type, you can make it an ARC-managed type by wrapping it in a typedef with __attribute__((NSObject)).

The Retainable object pointers section of the ARC specification says:

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.)
  • typedefs marked with __attribute__((NSObject))

(emphasis on last item added by me)

So if you make a typedef like this:

typedef __attribute__((NSObject)) CGImageRef MyImageRef;

and declare your property like this:

@property (nonatomic, strong) MyImageRef loupeImage;

the underlying variable will be managed by ARC (because the underlying variable will have the typedef'd type, which is an ARC-managed type) and you will not have to nil it in dealloc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文