4

我在ARC关于weak物业的疑问(自动引用计数)Objective-C的 - 弱属性 - 吸气自动释放(自动引用计数)

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

weak属性的行为与assign属性类似,不同之处在于,当属性指向的实例被破坏时,ivar会指向nil。

问:

  1. 我只是觉得weak属性的getter保留并自动释放。是不是想表现得像在assign财产的getter设置吸气剂不保留,并自动释放(请参阅程序)

计划:

我已经计划如下与实际产出和我的预期产出。

注意 - 当我改变从weak属性为assign我的期望输出满足

#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); 
} 

实际输出:

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 

感谢

回答

4

上的属性供应weak承担伊娃__weak所有权,即它只是@synthesize的指令。

根据http://clang.llvm.org/docs/AutomaticReferenceCounting.html§4.2,读__weak变量需要保持所述对象(和后解除,当然):对一个对象左值一个左值到右值转换时,会发生

读。

  • 对于__弱对象,当前指针被保留,然后在当前完整表达式结束时释放。这必须以原子方式执行任务和指出对象的最终版本。
  • 对于所有其他对象,左值用原语语义加载。

它没有说为什么,但想想,如果你从__weak变量得到了对象死亡之前,你使用它甚至开始会发生什么。弱指针的目的是为了确保你有nil或有效的对象具有生命周期,这就是为什么阅读它的值意味着保留指针(然后属性的getter返回它自动释放)。

这不是Obj-C所特有的,它是所有弱指针实现(包括refcounted和垃圾收集)的常见习惯用法。弱指针不能直接发出指针值,它们必须创建强指针来保持对象,以确保它在调用者开始使用它之前不会死亡。在Obj-C中,它是retain-autorelease;在C++中,weak_ptr首先创建shared_ptr,在垃圾收集环境中,返回一个强引用,并且该对象的生命期被无声地延长。

+0

感谢您的答复保留, 我有个疑问。纠正我,如果我错了 - 使用弱财产的目的是确保寿命不增加,只要使用它,只要所有者不摧毁它。如果要延长生命期,是否会违背使用弱指针的目的? – user1046037

+0

@ user1046037我已经更新了我的答案,并附有一个ARC规范的链接,明确说明了这种行为。 – hamstergene

+0

@ user1046037属性上的'weak'只是'@ synthesize'的一条指令。你正在观察的行为是由于'__weak'读取语义导致的:你不能将weak转换为'unsafe_unretained'指针,因为它的生命周期可能在任何时候结束,你必须在使用它之前保留该对象。 – hamstergene

0

返回一个适合X1的样子:

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获取属性得到自动释放呼叫,并通过autoreleasepool