Objective-C - 弱属性 - getter autoreleases(自动引用计数)

发布于 2024-12-16 01:04:08 字数 1970 浏览 3 评论 0原文

我对 ARC(自动引用计数)中的 weak 属性有疑问

我的理解(如果我错了请纠正我):

weak 属性的行为类似到 assign 属性,除了当该属性指向的实例被销毁时,ivar 会指向 nil。

问题:

  1. 我只是觉得weak属性的getter保留并自动释放。它不是应该像 assign 属性的 getter 一样,其中 getter 不保留和自动释放吗?(请参阅程序)

程序:

我在下面给出了具有实际输出和我的预期输出的程序。

注意 - 当我将属性从weak更改为分配时,我的预期输出得到满足

#import<Foundation/Foundation.h>

@interface A : NSObject
- (void) dealloc;
@end

@implementation A
- (void) dealloc
{
    printf("\tinstance of A deallocated = %p\n", self);
}
@end

@interface B : NSObject
@property (weak) A* xa1;
- (void) dealloc;
@end

@implementation B
@synthesize xa1;
- (void) dealloc
{
    printf("\tinstance of B deallocated = %p\n", self);
}
@end


int main()
{
    B* b1 = [[B alloc] init];

    @autoreleasepool                        //autoreleasepool 1
    {   
        {                                   //block 1
            A* a1 = [[A alloc] init];
            printf("\ta1 = %p\n", a1);

            b1.xa1 = a1; 

            A* a3 = b1.xa1;

            printf("--- end of block 1\n");
        }                                       //at this point i expected instance pointed by a1 to be destroyed

        printf("--- end of autoreleasepool 1\n");
    }   

    printf("---- end of main\n");

    return(0);
}

实际输出:< /strong>

    a1 = 0x10d713f50
--- end of block 1
--- end of autoreleasepool 1
    instance of A deallocated = 0x10d713f50
---- end of main
    instance of B deallocated = 0x10d713d30

我的预期输出:

    a1 = 0x10d713f50
--- end of block 1
    instance of A deallocated = 0x10d713f50
--- end of autoreleasepool 1
---- end of main
    instance of B deallocated = 0x10d713d30

谢谢

I have a doubt regarding weak property in ARC (auto reference counting)

My understanding (correct me if I am wrong):

weak property behaves similar to the assign property except that when the instance that the property was pointing to gets destroyed, the ivar is made to point to nil.

Question:

  1. I just feel that the getter of the weak property retains and autoreleases. Isn't it suppose to behave like getter of the assign property where the getter doesn't retain and autorelease ?(pls refer to the program)

Program:

I have given below the program with the actual output and my expected output.

Note - When I change property from weak to assign my expected output is met

#import<Foundation/Foundation.h>

@interface A : NSObject
- (void) dealloc;
@end

@implementation A
- (void) dealloc
{
    printf("\tinstance of A deallocated = %p\n", self);
}
@end

@interface B : NSObject
@property (weak) A* xa1;
- (void) dealloc;
@end

@implementation B
@synthesize xa1;
- (void) dealloc
{
    printf("\tinstance of B deallocated = %p\n", self);
}
@end


int main()
{
    B* b1 = [[B alloc] init];

    @autoreleasepool                        //autoreleasepool 1
    {   
        {                                   //block 1
            A* a1 = [[A alloc] init];
            printf("\ta1 = %p\n", a1);

            b1.xa1 = a1; 

            A* a3 = b1.xa1;

            printf("--- end of block 1\n");
        }                                       //at this point i expected instance pointed by a1 to be destroyed

        printf("--- end of autoreleasepool 1\n");
    }   

    printf("---- end of main\n");

    return(0);
}

Actual Output:

    a1 = 0x10d713f50
--- end of block 1
--- end of autoreleasepool 1
    instance of A deallocated = 0x10d713f50
---- end of main
    instance of B deallocated = 0x10d713d30

My Expected Output:

    a1 = 0x10d713f50
--- end of block 1
    instance of A deallocated = 0x10d713f50
--- end of autoreleasepool 1
---- end of main
    instance of B deallocated = 0x10d713d30

Thanks

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

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

发布评论

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

评论(2

-残月青衣踏尘吟 2024-12-23 01:04:08

在属性上提供 weak 会假定 ivar 拥有 __weak 所有权,即它只是 @synthesize 的指令。

根据 http://clang.llvm.org/docs/AutomaticReferenceCounting.html § 4.2,读取 __weak 变量需要保留该对象(当然,然后释放):

在对象左值上执行左值到右值转换时会发生读取。

  • 对于 __weak 对象,当前指针被保留,然后在当前完整表达式结束时释放。这必须针对分配和指向对象的最终发布以原子方式执行。
  • 对于所有其他对象,左值会加载原始语义。

它没有说明原因,但想一想如果从 __weak 变量获得的对象在您开始使用它之前就死掉了,会发生什么。弱指针的目的是确保您有 nil 或具有已知生命周期的有效对象,这就是为什么读取其值意味着保留指针对象(然后属性的 getter 返回它自动释放)。

这并不是 Obj-C 独有的,它是所有弱指针实现(引用计数和垃圾收集)的常见习惯用法。弱指针不能直接给出指针值,它们必须创建指向“持有”对象的强指针,以确保它在调用者开始使用它之前不会消失。在Obj-C中,是retain-autorelease;在C++中,weak_ptr首先创建shared_ptr,在垃圾收集环境中,返回强引用并默默延长对象的生命周期。

Supplying weak on a property assumes __weak ownership for the ivar, i.e. it's just an instruction for @synthesize.

According to http://clang.llvm.org/docs/AutomaticReferenceCounting.html §4.2, reading __weak variable requires retaining the object (and releasing after, of course):

Reading occurs when performing a lvalue-to-rvalue conversion on an object lvalue.

  • For __weak objects, the current pointee is retained and then released at the end of the current full-expression. This must execute atomically with respect to assignments and to the final release of the pointee.
  • For all other objects, the lvalue is loaded with primitive semantics.

It does not say why, but think of what happens if the object you got from __weak variable dies before you even started using it. The purpose of weak pointer is to make sure you have either nil or a valid object with well-known lifetime, that is why reading its value implies retaining the pointee (and then property's getter returns it autoreleased).

This is not unique to Obj-C, it's common idiom to all weak pointer implementations (both refcounted and garbage collected). Weak pointers can not give out pointer value directly, they have to create strong pointer to 'hold' object to make sure it won't die before caller has even started using it. In Obj-C, it's retain-autorelease; in C++, weak_ptr creates shared_ptr first, in garbage-collected environments, a strong reference is returned and the object's lifetime is prolonged silently.

淡墨 2024-12-23 01:04:08

x1 的 Getter 看起来像:

function -[B xa1] {
    var_8 = rdi;
    var_0 = rsi;
    rdi = objc_loadWeakRetained(var_8 + *_OBJC_IVAR_$_B.xa1);
    rax = [rdi autorelease];
    return rax;
}

因此,当您获取

A* a3 = b1.xa1;

a1 == b1.xa1 中的属性时,将获得 autorelease 调用并由 autoreleasepool 保留

Getter for x1 looks like:

function -[B xa1] {
    var_8 = rdi;
    var_0 = rsi;
    rdi = objc_loadWeakRetained(var_8 + *_OBJC_IVAR_$_B.xa1);
    rax = [rdi autorelease];
    return rax;
}

So when you get property in

A* a3 = b1.xa1;

a1 == b1.xa1 get autorelease call and retained by autoreleasepool

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