Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何增加NSString类型变量的保留计数?_Iphone_Ios_Objective C - Fatal编程技术网

Iphone 如何增加NSString类型变量的保留计数?

Iphone 如何增加NSString类型变量的保留计数?,iphone,ios,objective-c,Iphone,Ios,Objective C,下面是关于增加NSString类型变量的d retain count值的程序 在接口部分,我已经声明了 @property (strong,nonatomic)NSString *str1; @property (strong, nonatomic)NSString *str2; -(IBAction)goBtn:(id)sender; 和ind实现部分,我定义了以下内容 - (IBAction)goBtn:(id)sender { self.str1=[[NSString alloc]

下面是关于增加NSString类型变量的d retain count值的程序 在接口部分,我已经声明了

@property (strong,nonatomic)NSString *str1;
@property (strong, nonatomic)NSString *str2;
-(IBAction)goBtn:(id)sender;
和ind实现部分,我定义了以下内容

- (IBAction)goBtn:(id)sender {
   self.str1=[[NSString alloc]init];
   self.str1=self.str2;
   self.str2=[self.str1 retain];
   self.str2=[[NSString alloc]init];
   self.str2=self.str1;
   self.str1=[self.str2 retain];
   self.str2=[self.str1 retain];
   NSLog(@"retain count is %i", self.str1.retainCount);
   NSLog(@"retain count of str2 is %i", self.str2.retainCount);
}
但结果是 保留计数为0 str2的保留计数为0


为什么会发生这种情况??代码有什么错误吗?

保留计数没有意义。别担心。它涉及到很多复杂的因素,比如NSString是一个类集群,实现细节实际上不是您的问题

更重要的是,您的财产申报不正确

自动保留计数(ARC) 保留/释放 进一步讨论 正如斯文(下文)指出的,从技术上讲,保留和强大是同义词。然而,我认为区分代码处于ARC或保留/释放状态是很重要的。一些一般最佳做法:

仅使用_ivar在init和dealloc中引用ivar,如果不使用ARC,则在此处使用调用来保留/释放。无需在ARC下解除锁定

- (id)initWithString:(NSString *)string
{
   self = [super init];
   if (self != nil) {
      _retainString = [string retain]; // Adds 1 to retain count
   }

   return self;
}

- (void)dealloc
{
   [_retainString release]; // Decrement retain count by 1

   [super dealloc]; 
}
其余时间使用self.ivar调用getter/setter。这会自动处理正确的行为

- (void)doSomethingWithString:(NSString *)string
{
   self.retainString = string; // Adds 1 to retain count
}
如果您决定在声明的属性中重写getter/setter,那么您将引用_ivar并手动调用retain或release。如果使用ARC,则不需要调用保留/释放

- (void)setRetainString:(NSString *)string
{
    if (_retainString != string) {
       [_retainString release];
       _retainString = [string retain];
    }
}

你应该经常分析你的代码来验证你没有把事情搞砸。它通常会显示您的逻辑失败。

您向nil发送了大量消息,这就是为什么您的保留计数为0

在这里,我再次写下了您的代码,其中包含了变量更改时的新值:

str1和str2为零

self.str1=[[NSString alloc]init];
str1是空字符串

self.str1=self.str2;
self.str2=self.str1;
str1为零

self.str2=[self.str1 retain];
self.str2=[[NSString alloc]init];
str2是空字符串

self.str1=self.str2;
self.str2=self.str1;
str2为零

self.str1=[self.str2 retain];
self.str2=[self.str1 retain];
最后,str1和str2都为零,因此保留计数为零

但即使不是每次都用nil覆盖新字符串,也不会得到预期的结果。让我们考虑一下:

self.str1 = [[NSString alloc] init]
self.str2 = [[NSString alloc] init]
如果你查看他们的保留计数,你会得到18446744073709551615(在Mac OS X上,64位)。然后,如果查看指针的值,就会发现它们都相等,因此在调用
[[NSString alloc]init]
的两次调用中,都得到了相同的空NSString对象

这实际上是有道理的。NSString对象是不可变的,这意味着一旦创建它们,它们就永远无法更改。因此,在空字符串的多个相同副本上浪费内存是没有意义的

其中一些共享实例从其retainCount方法返回可能的最大值,以显示它们是单例的事实。但不是所有的

因此,对象的保留计数不是很有用。有些东西在撒谎。而在真正的应用程序中,它仍然常常不是你所期望的。有时系统会将对象保留一段时间,即使您自己没有保留它


但是我猜您正在尝试学习保留/释放内存模型是如何工作的(这是必要的,即使您使用的是ARC)。为此,您可以查询保留计数。但是您应该直接使用基类
NSObject
,因为它不会对retain计数器执行任何特殊的操作。您需要记住,一旦您将测试对象传递给某些系统方法,您的保留计数可能会在以后出现意外情况。请始终记住,永远不要在实际应用程序中查询保留计数-这是无用的。

strong和retain是同义词,这不是问题。@Sven这在风格上是灾难性的。他很可能混淆了基本概念,而区别是非常重要的。对初学者来说可能会混淆,但一旦你知道系统是如何工作的,这应该不会是一个问题。毕竟,参考计数机制不会随着ARC而消失。当然,您应该总是为新的ARC代码编写
strong
,但是如果您使用的是为手动内存管理编写的旧代码,并且以后转换为ARC,那么您几乎总是可以同时看到这两个代码。字符串属性应该是copy。如果传递一个可变字符串,init方法会做非常糟糕的事情……是的,如果你习惯传递可变字符串。然而,这里的要点只是演示如何保留和释放。复制和在对象中复制的实现完全是另一回事。请查看此站点,了解何时使用保留计数:在零上捕获良好。我以为他把它放在别的地方了。当我看到那个代码块时,我只看到绝望。对不起,先生,但是当我没有用nil覆盖我的新字符串时,意思是self.str1=self.str2;如果不使用versa,则其输出总是-1。为什么会这样??保留计数是否可以为负???否,保留计数不能为负,它是一个无符号整数。如果得到的是负数,则将其打印为有符号整数。被解释为无符号整数的有符号整数-1的位模式将给出可能的最大值(对于给定的位大小)。尝试用
%u
而不是
%i
打印它。好的。。。现在我明白了。。