[英]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 thename
property strongly.我知道
self
会强烈保留name
属性。 But how will thename
property relate toself
?但是,
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
的引用,因此strong
和weak
属性不适用。 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.