Reputation: 612
My question is two-part:
First, Say I have a 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
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.
Second, if I add a method which has a block that references the name property. So my updated implementation of MyClass.m is:
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?
Upvotes: 1
Views: 74
Reputation: 16650
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.
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. 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.
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. 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.
Upvotes: 1
Reputation: 7552
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. 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.
Upvotes: 1
Reputation: 122381
I know that
self
will hold thename
property strongly. But how will thename
property relate toself
?
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. 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. 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.
Upvotes: 2
Reputation: 3690
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.
2: In the following code
-(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"];
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.
Upvotes: 2
Reputation: 31016
First: The name property holds no relationship to MyClass
, weak or otherwise. (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.)
Second: Since you're simply executing the block rather than storing it, I don't see an opportunity for a retain cycle.
Upvotes: 2