我观察到以下行为。
取两个属性变量。
@property (nonatomic, retain) NSString *stringOne;
@property (nonatomic, assign) NSString *stringTwo;
在.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]);
由于alloc,localstring的保留计数为1。现在我给了 self.stringOne = localString。
由于stringOne的retain属性,localstring的保留计数将变为2。现在我给了 self.stringTwo = localString。
即使在这里,localstring保留计数也会增加1。请注意,我已将assign属性赋予stringTwo。实际上,localstring或stringTwo的保留计数不应该增加1,因为它是assign属性。 如果我错了,请纠正我。
由于 Jithen
答案 0 :(得分:5)
转储retainCount
;它没用。 http://www.whentouseretaincount.com/
你的困惑的根源在于不了解指针是如何工作的。像这样修改你的代码:
@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
它会出现这样的事情:
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
只有一个字符串实例在播放; localstring
,stringOne
和stringTwo
都只包含对 NSMUtableString 的一个实例的引用。
因此,您会看到alloc
的一个字符串实例的+1 RC ,stringOne
属性的分配+1,stringTwo
属性没有变化{1}}。
(RC只应该根据增量进行推理;如果保留一个对象,则需要在不再需要该对象时将其与一个版本进行平衡。该对象可能被其他东西保留是无关紧要的。)
答案 1 :(得分:3)
当我运行此代码时:
@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
我收到了这个控制台日志:
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
所有这些价值观都与人们期望的完全一样。
首次创建局部变量引用的对象时,该对象的保留计数为+1
。
当您设置retain
属性stringOne
时,对象的保留计数将增加到+2
,同时localstring
和{{1}引用同一个对象,它们都会报告相同的stringOne
。
但是,当您使用retainCount
属性assign
时,stringTwo
不会更改。
答案 2 :(得分:2)
当您使用retain
声明属性时,它会自动“保留”该对象,从而增加其保留计数。
因此NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
使保留计数= 1;
然后self.stringOne = localstring;
使保留计数= 2。
我的想法是,如果属性被保留,那么在此行之后 self.stringOne = localstring,self.stringone的保留计数 应该成为一个
创建对象时,它将以保留计数1开始。
答案 3 :(得分:1)
首先,永远不要使用retainCount
。它根本不可靠,因为它是全局保留计数,并且可能受到代码之外的其他因素的影响。令人惊讶的是,在这种情况下,它是正确的。我们来看看:
//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;
请注意,现在localstring
,self.stringOne
和self.stringTwo
都指向内存中的相同位置。每次使用=
符号时,你都不复制内存内容(你的思维方式似乎表明你认为它是如何工作的)。你只是将另一个变量指向内存中的一个位置并说“在我这么说之前不要释放这块内存”。 (至少在保留属性的情况下)。
结论:localstring的retain count,self.stringOne的retain count和self.stringTwo的retain count都是相同的。
旁注:对象的保留计数为零是不可能的。唯一可能发生的时间是retainCount
发送到nil
时(我认为self.stringOne
是您测试时){/ p>
答案 4 :(得分:0)
虽然在编写代码时查看retainCount
绝不是一个好主意,但在这种情况下它的行为应该是正常的。我认为你对内存管理的理解似乎有点过时了。
要回答你的问题,
NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];
这会创建一个可变字符串 Object ,递增其保留计数并返回指向它的指针。请注意,retainCount
与对象相关联,而非指针。
将其分配给保留属性时,
self.stringOne = localstring;
它将retain
传递给您的对象,并再次将其保留计数增加1。现在,对象的保留计数为2,两个指针都指向同一个对象。因此,当您记录retainCount
时,您将获得所需的信息。希望这能回答你的问题。