属性 与 "self" 和 vice-versa 有什么关系?

How is a property related to "self" and vice-versa?

我的问题是two-part:

首先,假设我有一个class:

MyClass.h

@interface MyClass: NSObject

-(id)initWithName:(NSString*)name;

@property(nonatomic, strong) NSString *name;

@end

MyClass.m

@implementation MyClass

-(id)initWithName:(NSString*)name
{
    if (self = [super init])
    {
        self.name = name;
    }
    return self;
}

@end

我的问题:我知道 self 会强烈保留这个名字 属性。但是名字 属性 和自己有什么关系呢?我的意思是我可以访问 name 作为 self.name 但是当 class 实例化时,self(在本例中是 name)的 children 与 self 有什么关系?我将 class 的结构想象成一棵树,其中 parent 持有对 children 的强引用,而 children 持有对 [=54= 的弱引用].我想知道我的想法是否正确。我猜这将是一段微弱的关系。

Second,如果我添加一个方法,该方法有一个引用名称 属性 的块。所以我更新的 MyClass.m 实现是:

MyClass.m

@implementation MyClass

-(id)initWithName:(NSString*)name
{
    if (self = [super init])
    {
        self.name = name;
    }
    return self;
}

-(void)doSomeStuff
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        self.name = @"Name changed inside block";
}];
}

@end

我的第二个问题是:我没有在我的块中直接引用 self。所以,我想这里没有保留周期。但是我引用的是自己持有的名称属性。那么这会创建一个保留周期吗?

首先:名称 属性 与 MyClass 无关,弱或其他。 (也就是说,如果您将 name 传递给某个任意方法,它不会携带对 MyClass 实例的任何引用,而它是 属性。)

第二:因为你只是在执行块而不是存储它,所以我看不到保留周期的机会。

1:MyClass实例保留了name属性,name属性本身不知道什么是MyClass和因此,没有任何内容从 String-name 指向 MyClass 本身。

2:在下面的代码中

-(void)doSomeStuff
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        self.name = @"Name changed inside block";
}];
}

self.name = @"Name changed inside block"; 等同于 [self setName:@"Name changed inside block"];

所以你实际上是在块中保留 MyClass 实例,然后执行它的方法来更新名称,(块需要指向这个名称的指针来更改它,对吗?块保留 class 对象包含此 属性 ) ,您不会保留 属性 名称本身。

I know that self will hold the name property strongly. But how will the name property relate to self?

每个 属性 将有一个 支持实例变量 ,通常命名为与 属性 相同的前导下划线和 getter and/or setter 方法。没有关系; 属性 通常使 class 实例更大(由于额外的实例变量)和 class 更大(由于额外的方法)。

I am not referencing self directly inside my block. So, I guess there is no retain cycle here. But I am referencing name property which is held by self. So does this create a retain cycle?

是的,您直接引用了 self,因此可以使用保留循环。然而,保留循环只能在特定情况下发生,通常通过创建对 self 的弱引用并在块中使用它来避免这种情况更安全。

但是名字 属性 与自己有什么关系呢?我猜这将是一段微弱的关系。

name 属性 没有对 self 的引用,因此属性 strongweak 不适用。对象实例只是实例变量的集合,聚集到一个结构中。当我们谈论对象内存管理时,我们谈论的是包含该结构的内存。说 属性(实际上支持 属性 的实例变量)引用任何东西是没有意义的。它只是 self 的一部分。

My question: I know that self will hold the name property strongly. But how will the name property relate to self? What I mean is that I can access name as self.name but while class instantiation, how is the children of self (which in this case is name) related to self? I am imagining the structure of the class as a tree, with the parent holding strong reference to the children and the children holding a weak reference to the parent. I want to know if I am thinking about it correctly or not. My guess is it will be a weak relationship.

children 可以 引用 parent 然后它应该是弱的,因为你提到的原因。但是 NSString 个实例没有这样的 up-reference。所以不能有一个保留周期。

一般情况下,由您来管理这种反向关系。 (核心数据在其默认设置器中自动执行,如果您插入反向关系。)没有自动完成,没有 up-reference 的定义,没有 up-reference 的设置。

My second question is: I am not referencing self directly inside my block. So, I guess there is no retain cycle here. But I am referencing name property which is held by self. So does this create a retain cycle?

您在块内引用 self,因为您使用它。时期。

但是一个循环引用需要两个引用。只要在块内使用 self,但块没有存储在 self 的 属性 中(直接或间接),就不会发生保留循环。