繁体   English   中英

iOS保留,分配

[英]IOS retain , Assign

我观察到以下行为。

接受了两个属性变量。

@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]);

在这里,由于分配,localstring保留计数为1。 现在我给了self.stringOne = localString。

由于stringOne的keep属性,localstring的保留计数将变为2。 现在我给了self.stringTwo = localString。

即使在这里,本地字符串保留计数也增加一。 请注意,我已经为stringTwo提供了assign属性。 实际上,localstring或stringTwo的保留计数不应为1,因为它是assign属性。 如果我错了,请纠正我。

谢谢吉森

转储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

播放中只有一个字符串实例; localstringstringOnestringTwo都保留对NSMUtableString的一个实例的引用

因此,你会看到一个字符串实例的 +1 RC,对于alloc ,一为分配到stringOne财产,并且没有改变stringTwo

(RC仅应以增量为依据进行推理;如果保留一个对象,则在不再需要该对象时需要将其与发行版之间进行权衡。该对象可能被其他对象保留是无关紧要的。)

当我运行这段代码时:

@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 ,并且当localstringstringOne引用同一对象时,它们都将报告相同的retainCount

  • 但是,当您使用assign属性stringTworetainCount不会更改。

当你声明一个属性与retain ,它会自动“保留”的对象,从而提高其保留计数。

因此, NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"]; 使保留计数= 1;

然后self.stringOne = localstring; 使保留计数= 2。

我的想法是,如果给定该属性的保留,那么在这一行self.stringOne = localstring之后,self.stringone的保留计数应变为1

创建对象时,它将以保留计数1开始。

首先,永远retainCount对任何东西使用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;


注意,现在localstringself.stringOneself.stringTwo都指向内存中的同一位置。 并不是在每次使用=符号时都复制内存内容(您的思维方式似乎表明您认为这是工作原理)。 您只是将另一个变量指向内存中的某个位置,然后说:“除非我这样说,否则请不要释放这块内存。” (至少在保留属性的情况下)。

结论:localstring的保留计数,self.stringOne的保留计数和self.stringTwo的保留计数都相同。

旁注:对象的保留计数不可能为零。 唯一可能发生的时间是将retainCount发送到nil (我假设self.stringOne是在测试时)

虽然在编写代码时始终查看retainCount从来都不是一个好主意,但在这种情况下,它的表现应是正常的。 我认为您对内存管理的理解似乎有些偏离。

为了回答您的问题,

NSMutableString *localstring= [[NSMutableString alloc] initWithString:@"test"];

这将创建一个可变的字符串Object ,增加其保留计数并返回指向它的指针。 请注意, retainCount对象而不是指针关联。

当您将其分配给保留属性时,

self.stringOne = localstring;

它将retain传递给您的对象,并将其保留计数再次增加1。 现在,您的对象的保留计数为2,并且两个指针都指向同一对象。 因此,当您记录retainCount ,您将获得所得到的。 希望这能回答您的问题。

暂无
暂无

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

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