简体   繁体   English

财产与“自我”有什么关系,反之亦然?

[英]How is a property related to “self” and vice-versa?

My question is two-part: 我的问题分为两部分:

First , Say I have a class: 首先 ,假设我有一个课程:

MyClass.h MyClass.h

@interface MyClass: NSObject

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

@property(nonatomic, strong) NSString *name;

@end

MyClass.m MyClass.m

@implementation MyClass

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

@end

My question: I know that self will hold the name property strongly. 我的问题:我知道自己会坚决拥有name属性。 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? 我的意思是我可以将名称作为self.name进行访问,但是在类实例化时,self的子代(在本例中为name)与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. 我猜这将是一种脆弱的关系。

Second , if I add a method which has a block that references the name property. 其次 ,如果我添加了一个包含引用name属性的块的方法。 So my updated implementation of MyClass.m is: 因此,我更新的MyClass.m实现是:

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

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? 那么这会形成保留周期吗?

First: The name property holds no relationship to MyClass , weak or otherwise. 第一:name属性与MyClass无关,无论是否弱。 (That is, if you pass name to some arbitrary method, it doesn't carry any reference to the MyClass instance where it was a property.) (也就是说,如果您将name传递给某个任意方法,则该name将不带有对作为属性的MyClass实例的任何引用。)

Second: Since you're simply executing the block rather than storing it, I don't see an opportunity for a retain cycle. 第二:由于您只是执行块而不是存储块,因此我看不到保留周期的机会。

1: The MyClass instance has retained the name property, name property itself has no idea what is MyClass and therefore , there is nothing referring from String-name to the MyClass itself. 1: MyClass实例保留了name属性, name属性本身不知道什么是MyClass ,因此,从String-name到MyClass本身都没有引用。

2: In the following code 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"; is the same as [self setName:@"Name changed inside block"]; [self setName:@"Name changed inside block"];

So you are actually retaining MyClass instance inside Block and then executing its method to update the name , ( block needs pointer to this Name to change it , right ? block retains class object which contains this property ) , you are not retaining the property name itself. 因此,您实际上是将MyClass实例保留在Block中,然后执行其方法来更新名称,(block需要指向该Name的指针才能对其进行更改,对吗?block保留了包含此属性的类对象),而您并未保留属性名本身。

I know that self will hold the name property strongly. 我知道self会强烈保留name属性。 But how will the name property relate to self ? 但是, name属性将如何与self

Each property will have a backing instance variable , conventionally named the same as the property with a leading underscore and a getter and/or setter method. 每个属性都有一个后备实例变量 ,通常与该属性同名,并带有一个下划线和一个getter和/或setter方法。 There is no relationship; 没有关系; the property generally makes the class instance larger (due to additional instance variable) and the class larger (due to additional methods). 该属性通常会使类实例变大(由于附加的实例变量),而使类变大(由于附加的方法)。

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? 那么这会形成保留周期吗?

Yes you are referencing self directly, so a retain cycle is possible. 是的,您直接引用了self ,因此可以进行保留。 However a retain cycle can only happen under certain circumstances, and it's often just safer to avoid this by creating a weak reference to self and using that within the block. 但是,保留周期只能在某些情况下发生,通常通过创建对self的弱引用并在块中使用它来避免这种情况更安全。

But how will the name property relate to self? 但是名称属性将如何与自我相关? My guess is it will be a weak relationship. 我猜这将是一种脆弱的关系。

The name property does not have a reference back to self , so the attributes strong and weak don't apply. name属性没有对self的引用,因此strongweak属性不适用。 An object instance is just a collection of instance variables, gathered into a struct. 对象实例只是实例变量的集合,收集到一个结构中。 When we talk about object memory management, we are talking about the memory containing that struct. 当我们谈论对象内存管理时,我们谈论的是包含该结构的内存。 It doesn't make sense to say that a property (really the instance variable backing the property) has a reference to anything. 说一个属性(实际上是支持该属性的实例变量)具有对任何事物的引用是没有意义的。 It is simply one part of what self is. 它仅仅是self一部分。

My question: I know that self will hold the name property strongly. 我的问题:我知道自己会坚决拥有name属性。 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? 我的意思是我可以将名称作为self.name进行访问,但是在类实例化时,self的子代(在本例中为name)与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. 我猜这将是一种脆弱的关系。

The children can have a reference to the parent and then it should be weak for the reasons you mentioned. 子代可以参考父代,然后由于您提到的原因,它应该比较弱。 But NSString instances does not have such an up-reference. 但是NSString实例没有这样的向上引用。 So there cannot be a retain cycle. 因此,不可能有保留周期。

In general it is up to you to manage such inverse relationship. 通常,您需要管理这种逆关系。 (Core Data does it automatically in its default setters,if you insert a inverse relationship.) Nothing is done automatically, no definition of an up-reference, no setting of a up-reference. (如果插入逆关系,则Core Data会在其默认设置器中自动执行此操作。)不会自动完成任何操作,也不会定义向上参考,也不会设置向上参考。

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? 那么这会形成保留周期吗?

You refer self inside the block, because you use it. 您在块内引用了self ,因为您使用了它。 Period. 期。

But a retain cycle needs two references. 但是保留周期需要两个参考。 As long as self is used inside the block, but the block is not stored in a property of self (directly or indirectly) no retain cycle can occur. 只要在块内部使用了self ,但是块没有以self的属性(直接或间接)存储,就不会发生保留周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM