[英]IOS retain , Assign
I observed the following behavior. 我观察到以下行为。
Took two property variables. 接受了两个属性变量。
@property (nonatomic, retain) NSString *stringOne;
@property (nonatomic, assign) NSString *stringTwo;
In .m file written below code.. 在.m文件下面的代码中写..
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
self.stringOne = localstring;
NSLog(@"localstring = %d", [string retainCount]);
NSLog(@"string one retain count = %d", [self.stringOne retainCount]);
self.stringTwo = localstring;
NSLog(@"localstring = %d", [localstring retainCount]);
NSLog(@"string two retain count = %d", [self.stringTwo retainCount]);
Here localstring retain count is 1 because of alloc. 在这里,由于分配,localstring保留计数为1。 Now i gave self.stringOne = localString.
现在我给了self.stringOne = localString。
The retain count of localstring will become two because of retain property of stringOne. 由于stringOne的keep属性,localstring的保留计数将变为2。 Now i gave self.stringTwo = localString.
现在我给了self.stringTwo = localString。
Even here the localstring retain count is incremented by one. 即使在这里,本地字符串保留计数也增加一。 Notice that i have given assign property to stringTwo.
请注意,我已经为stringTwo提供了assign属性。 Practically the retain count of localstring or stringTwo should not increase by 1 as it is assign property.
实际上,localstring或stringTwo的保留计数不应为1,因为它是assign属性。 Please correct me if i am wrong.
如果我错了,请纠正我。
Thanks Jithen 谢谢吉森
Dump the retainCount
; 转储
retainCount
; it is useless. 这是没有用的。 http://www.whentouseretaincount.com/
http://www.whentouseretaincount.com/
The source of your confusion is in not understanding how pointers work. 您困惑的根源在于不了解指针的工作方式。 Modify your code like this:
像这样修改您的代码:
@interface BBQ:NSObject
@property (nonatomic, retain) NSString *stringOne;
@property (nonatomic, assign) NSString *stringTwo;
@end
@implementation BBQ
- (void) burn
{
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
self.stringOne = localstring;
NSLog(@"localstring = %p", localstring);
NSLog(@"string one = %p", self.stringOne);
self.stringTwo = localstring;
NSLog(@"localstring = %p", localstring);
NSLog(@"string two = %p", self.stringTwo);
}
@end
It'll spew something like this: 它会喷出这样的东西:
2013-04-11 08:48:13.770 asdffadsfasddfsa[18096:303] localstring = 0x10010aaf0
2013-04-11 08:48:13.772 asdffadsfasddfsa[18096:303] string one = 0x10010aaf0
2013-04-11 08:48:13.772 asdffadsfasddfsa[18096:303] localstring = 0x10010aaf0
2013-04-11 08:48:13.772 asdffadsfasddfsa[18096:303] string two = 0x10010aaf0
There is only one string instance in play; 播放中只有一个字符串实例;
localstring
, stringOne
, and stringTwo
all hold references to exactly one instance of NSMUtableString . localstring
, stringOne
和stringTwo
都保留对NSMUtableString的一个实例的引用 。
Thus, you'll see +1 RC of that one string instance for the alloc
, +1 for the assignment to the stringOne
property and no change for stringTwo
. 因此,你会看到一个字符串实例的 +1 RC,对于
alloc
,一为分配到stringOne
财产,并且没有改变stringTwo
。
(RC's should only be reasoned about in terms of deltas; if you retain an object, you need to balance that with a release when you no longer need the object. That the object may be retained by something else is irrelevant.) (RC仅应以增量为依据进行推理;如果保留一个对象,则在不再需要该对象时需要将其与发行版之间进行权衡。该对象可能被其他对象保留是无关紧要的。)
When I ran this code: 当我运行这段代码时:
@interface ViewController ()
@property (nonatomic, retain) NSString *stringOne;
@property (nonatomic, assign) NSString *stringTwo;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self test];
}
- (void)test
{
NSMutableString *localstring = [[NSMutableString alloc] initWithString:@"test"];
NSLog(@"localstring (before setting `stringOne` or `stringTwo`) = %d", [localstring retainCount]);
self.stringOne = localstring;
NSLog(@"localstring (after setting `stringOne`) = %d", [localstring retainCount]);
NSLog(@"string one retain count = %d", [self.stringOne retainCount]);
self.stringTwo = localstring;
NSLog(@"localstring (after setting `stringTwo`) = %d", [localstring retainCount]);
NSLog(@"string two retain count = %d", [self.stringTwo retainCount]);
}
@end
I received this console log: 我收到以下控制台日志:
localstring (before setting `stringOne` or `stringTwo`) = 1 localstring (after setting `stringOne`) = 2 string one retain count = 2 localstring (after setting `stringTwo`) = 2 string two retain count = 2
And all of those values are precisely as one would expect. 而所有这些值正是我们所期望的。
When you first create the object referenced by the local variable, that object has a +1
retain count. 首次创建由局部变量引用的对象时,该对象的
+1
保留计数。
When you set the retain
property, stringOne
, the object's retain count will be incremented to +2
, and as both localstring
and stringOne
reference that same object, they'll both report the same retainCount
. 设置
retain
属性stringOne
,对象的保留计数将增加为+2
,并且当localstring
和stringOne
引用同一对象时,它们都将报告相同的retainCount
。
But when you use the assign
property, stringTwo
, though, the retainCount
does not change. 但是,当您使用
assign
属性stringTwo
, retainCount
不会更改。
When you declare a property with retain
, it automatically 'retains' the object, thus increasing its retain count. 当你声明一个属性与
retain
,它会自动“保留”的对象,从而提高其保留计数。
So NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
因此,
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
makes retain count = 1; 使保留计数= 1;
Then self.stringOne = localstring;
然后
self.stringOne = localstring;
makes retain count = 2. 使保留计数= 2。
My thinking is if the property is given retain, then after this line self.stringOne = localstring , the retain count of self.stringone should become one
我的想法是,如果给定该属性的保留,那么在这一行self.stringOne = localstring之后,self.stringone的保留计数应变为1
When you create an object, it will start with a retain count of 1. 创建对象时,它将以保留计数1开始。
First of all, never use retainCount
for anything. 首先,永远
retainCount
对任何东西使用retainCount
。 It is simply not reliable since it is a global retain count, and can be influenced by other factors outside of your code. 由于它是全局保留计数,因此根本不可靠,并且可能会受到代码之外的其他因素的影响。 Amazingly, in this case, it is correct though.
令人惊讶的是,在这种情况下,它是正确的。 Let's examine:
让我们检查一下:
//Immediately localstring is +1 because you allocated it
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
//self.stringOne is a retain property, so localstring is incremented again (+2)
self.stringOne = localstring;
//self.stringTwo is a retain property, so localstring is incremented again (+3)
self.stringTwo = localstring;
Note that now localstring
, self.stringOne
and self.stringTwo
all point to the same location in memory. 注意,现在
localstring
, self.stringOne
和self.stringTwo
都指向内存中的同一位置。 You are not copying the memory contents every time you use the =
sign (your way of thinking seems to indicate that you think that is how it works). 您并不是在每次使用
=
符号时都复制内存内容(您的思维方式似乎表明您认为这是工作原理)。 You are simply pointing another variable at a location in memory and saying "Don't deallocate this piece of memory until I say so." 您只是将另一个变量指向内存中的某个位置,然后说:“除非我这样说,否则请不要释放这块内存。” (at least in the case of retain properties).
(至少在保留属性的情况下)。
Conclusion: localstring's retain count, self.stringOne's retain count, and self.stringTwo's retain count are all the same. 结论:localstring的保留计数,self.stringOne的保留计数和self.stringTwo的保留计数都相同。
Sidenote: It is impossible for an object to have a retain count of zero. 旁注:对象的保留计数不可能为零。 The only time that can happen is when
retainCount
is sent to nil
(which I assume self.stringOne
is when you test it) 唯一可能发生的时间是将
retainCount
发送到nil
(我假设self.stringOne
是在测试时)
While it is never a good idea to look at retainCount
when writing code, it is behaving as it should in this case. 虽然在编写代码时始终查看
retainCount
从来都不是一个好主意,但在这种情况下,它的表现应是正常的。 I think your understanding of memory management seems to be a little bit off. 我认为您对内存管理的理解似乎有些偏离。
To answer your question, 为了回答您的问题,
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
This creates a mutable string Object ,increments its retain count and returns a pointer to it. 这将创建一个可变的字符串Object ,增加其保留计数并返回指向它的指针。 Note that
retainCount
is associated with the Object and not the pointer. 请注意,
retainCount
与对象而不是指针关联。
When you assign it to your retain property, 当您将其分配给保留属性时,
self.stringOne = localstring;
it passes retain
to your Object and increments its retain count by 1 again. 它将
retain
传递给您的对象,并将其保留计数再次增加1。 Now your object's retain count is 2 and both the pointers point to the same object. 现在,您的对象的保留计数为2,并且两个指针都指向同一对象。 So, when you log
retainCount
, you get what you get. 因此,当您记录
retainCount
,您将获得所得到的。 Hope this answers your question. 希望这能回答您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.