使用(保留)属性时保留行为

发布于 2025-01-08 07:11:27 字数 1107 浏览 4 评论 0原文

大家好,我有一个关于以下问题的问题。

我有两个对象:aClass 和 bClass。 aClass 应通过使用保留属性包含 bClass。 实例化 bClass 后(我在这里没有使用方便分配器,因为我想解决这里的误解问题),通过使用 aClass 的 setProperty 将 bClass 分配给 aClass。

在整个过程中,我通过询问引用以及询问aClass的属性来检查bClass的retainCount。

据我了解,Objective C 的内存管理,提到的保留计数应该是相同的,因为我在属性和引用之间共享对象的所有权。

在我看来,我在理解内存管理方面有一个重大问题。也许有人可以向我解释我的错误。 提前谢谢。

Header of ClassA

@property (retain )ClassB *myProperty; 


Source of ClassA

@implementation ClassA
-(id)init {

self = [super init];

if (self) {
    ClassB * bClass = [[ClassB alloc] init];
    NSLog(@"Temporary bClass retain count = %d", [bClass retainCount]);

    self.myProperty = bClass;
    NSLog(@"retain count after giving ownership to ClassA = %d", [bClass retainCount]);

    [bClass release];
    NSLog(@"retain count of bClass after release = %d", [bClass retainCount]);
    NSLog(@"retain count of myProperty of ClassA = %d", [self.myProperty retainCount]);
}
return self;
}

输出为:

临时 bClass 保留计数 = 1

将所有权授予 ClassA 后保留计数 = 2

释放后 bClass 的保留计数 = 1

ClassA 的 myProperty 保留计数 = 2

Hello guys I've got a question regarding the following problem.

I have two objects: aClass and bClass. aClass shall contain bClass by using a retain property.
After instanciating bClass (I'm not using a convenience allocator here, because I want to solve my problem of missunderstanding here), bClass is assigned to aClass by using a setProperty of aClass.

Throughout the process I check the retainCount of bClass by asking the reference and also by asking the through the property of aClass.

As far as I understood, the memory managemend of Objective C, the mentioned retain counts should be the same, because I'm sharing ownership of an object between a property and a reference.

It seems to me I have a major problem in understanding the memory management. Maybe someone can explain to me my mistake.
Thx in advance.

Header of ClassA

@property (retain )ClassB *myProperty; 


Source of ClassA

@implementation ClassA
-(id)init {

self = [super init];

if (self) {
    ClassB * bClass = [[ClassB alloc] init];
    NSLog(@"Temporary bClass retain count = %d", [bClass retainCount]);

    self.myProperty = bClass;
    NSLog(@"retain count after giving ownership to ClassA = %d", [bClass retainCount]);

    [bClass release];
    NSLog(@"retain count of bClass after release = %d", [bClass retainCount]);
    NSLog(@"retain count of myProperty of ClassA = %d", [self.myProperty retainCount]);
}
return self;
}

The output is:

Temporary bClass retain count = 1 


retain count after giving ownership to ClassA = 2


retain count of bClass after release = 1 


retain count of myProperty of ClassA = 2

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

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

发布评论

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

评论(3

注定孤独终老 2025-01-15 07:11:27

对象实例被保留和释放。指向对象实例的指针不是对象,它们本身不会被保留或释放。

首先,您有一个名为 bClass 的指针,它指向 BCLass 的实例。当您调用 init 时,该实例将被保留。 (保留计数 = +1)

然后通过属性设置器 setMyProperty 分配另一个指针。由于该属性是与retsain属性合成的,因此BClass的实例再次被保留。 (Retain Count = +2)

接下来,对bClass 指向的BClass 实例调用release。 (这与 myProperty 属性所指向的 BClass 实例相同。(现在 Retain Count = +1。)

不使用非原子属性的效果可以从文档中看出:

默认情况下,属性是原子的,因此合成访问器可以提供对属性的可靠访问
在多线程环境中,即从 getter 返回的值或通过 setter 设置的值是
无论其他线程同时执行,始终完全检索或设置。

如果您指定强、复制或保留并且不指定非原子,则在引用计数中
环境中,对象属性的合成 get 访问器使用锁并保留和
自动释放返回的值 - 实现将类似于以下内容:

[_internal lock]; // lock using an object-level lock

id result = [[value retain] autorelease];

[_internal unlock];

return result;

因此,看起来您的日志记录语句引用了该属性,该属性保留了该对象 (Retain = +2) 并将其放入自动释放池中。 (释放将在稍后发生。

所有权只是意味着在释放对象时负责告诉对象该所有者不再需要它。取得所有权是通过保留对象实例(使用 New、Init、Retain ,或复制)。

Object instances are retained and released. Pointers to object instances are not objects and they, themselves do not get retained or released.

You first have a pointer called bClass pointing to an instance of BCLass. That instance is retained when you call init. (Retain count = +1)

Then you assign another pointer through the property setter setMyProperty. Since the property is sythesized with the retsain attribute, then the instance of BClass is retained again. (Retain Count = +2)

Next, you call release on the instance of BClass pointed to by bClass. (Which is the same instance of BClass that is pointed to by the myProperty property. (Retain Count = +1 now.)

The effect of not using the nonatomic attribute can be seen from the documentation:

Properties are atomic by default so that synthesized accessors provide robust access to properties
in a multithreaded environment—that is, the value returned from the getter or set via the setter is
always fully retrieved or set regardless of what other threads are executing concurrently.

If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted
environment, a synthesized get accessor for an object property uses a lock and retains and
autoreleases the returned value—the implementation will be similar to the following:

[_internal lock]; // lock using an object-level lock

id result = [[value retain] autorelease];

[_internal unlock];

return result;

So it looks like you logging statement references the property, which retains the object (Retain = +2) and puts it into the autorelease pool. (The release will happen later.

Ownership simply means to take responsibility for telling the object that it is no longer needed by that owner when the time comes to release it. Takiing owndership is done by retaining the object instance (with New, Init, Retain, or Copy).

旧时浪漫 2025-01-15 07:11:27

retainCount 没有用。别叫它。

特别是,它永远无法反映对象是否已自动释放,并且 atomic @property 将在调用 getter 方法时保留/自动释放对象。

retainCount is useless. Don't call it.

In particular, it can never reflect whether an object has been autoreleased and an atomic @property will retain/autorelease an object when the getter method is called.

寄离 2025-01-15 07:11:27

您需要记住的是,如果您分配它、复制它或新建它,那么您将获得一个对象的所有权,并且需要释放它。我不会担心保留计数的值。

All you need to remember is if you alloc it, copy it or new it, then you are taking ownership of an object and you need to release it. I wouldn't worry about the value of retainCount.

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