Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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
Objective c Cocoa/ObjC:我为属性IVAR分配对象的风格有什么性能缺陷吗?_Objective C_Cocoa_Memory Management_Properties - Fatal编程技术网

Objective c Cocoa/ObjC:我为属性IVAR分配对象的风格有什么性能缺陷吗?

Objective c Cocoa/ObjC:我为属性IVAR分配对象的风格有什么性能缺陷吗?,objective-c,cocoa,memory-management,properties,Objective C,Cocoa,Memory Management,Properties,我几乎在我的类需要IVAR的任何时候都使用属性。对于保留属性,我已经习惯了使用访问器方法分配/初始化实际IVAR的特定方式: - (void)anInitOrAccessorMethod { self.property = [[AClass alloc] init]; [self.property release]; } 每当我需要设置一个非自动释放的iVar时,我都会使用上面的样式设置属性(保留对象),然后向它发送一条释放消息来抵消alloc+retain。这与我看到的许多社区代码示

我几乎在我的类需要IVAR的任何时候都使用属性。对于保留属性,我已经习惯了使用访问器方法分配/初始化实际IVAR的特定方式:

- (void)anInitOrAccessorMethod
{
  self.property = [[AClass alloc] init];
  [self.property release];
}
每当我需要设置一个非自动释放的iVar时,我都会使用上面的样式设置属性(保留对象),然后向它发送一条释放消息来抵消alloc+retain。这与我看到的许多社区代码示例不同,在这些示例中,如果使用alloc/create创建对象,人们只需直接设置IVAR,从而消除了额外的发布


除了额外的代码开销之外,我的风格还有什么性能缺陷吗?

这在性能方面还不错,因为我不希望属性在紧循环中初始化,但如果您可以访问用作该项目后备存储的字段,那么可以更有效地进行初始化

- (void)anInitOrAccessorMethod
{
  self.property = [[AClass alloc] init];
  [self.property release];
}
本例中的保留/释放顺序如下(如您正确描述的):

如果您有权访问备份存储(假设iVar被称为
属性
),您可以放弃不必要的reatin/release调用(您也正确地提到了这一点):

由于未调用属性setter,因此retainCount将保持为1,提供与代码相同的行为

但在行为上有一个区别:直接访问备份存储区对于初始化属性来说是安全的(当它以前是
nil
时),因为setter无法再确保在设置新值之前释放以前的值


在性能方面:保留/释放实际上并不是一项成本高昂的操作。没有内存泄漏远比可能“保存”保留/释放调用更有价值。

不要这样做。如果您的属性被声明为具有
copy
语义,那么您的代码将泄漏第一个对象并覆盖第二个对象。

性能开销可能可以忽略不计,假设您的访问器没有代价高昂的副作用,但这就引出了在
-init
中不使用访问器的原因。您希望避免访问者对对象状态做出假设的错误。

复制我不这么认为。这个问题是“在您的init中使用点表示法有什么缺陷?”我的问题是“每次设置iVar时使用访问器和后续版本是否存在性能缺陷?”这可能发生在任何地方,而不仅仅是在init中。啊,是的,感谢您指出这一点。为了向可能阅读本文的任何其他人澄清……如果您在复制属性上执行此操作,您将获得:[属性发布];属性=[[newObject alloc]init]copy];[财产释放];上一个版本最终应用于新副本,而newObject永远不会被释放。您也不希望假定访问器本身的行为方式是特定的。Jonathan提出的关于复制属性的观点是最常见的错误;另一个原因是以后可以用自定义的访问器替换合成的访问器,还有一个原因是子类可以重写该访问器。
alloc: retainCount = 1 
retain: retainCount = 2  // (setter)
release: retainCount = 1
- (void)anInitOrAccessorMethod
{
  self.property_ = [[AClass alloc] init];
}