2011-08-15 93 views
1

我遇到了一些不熟悉的Objective-c内存管理代码。是什么区别:Objective-c对象释放模式

// no property declared for myMemberVariable in interface 
id oldID = myMemberVariable; 
myMemberVariable = [MyMemberVariable alloc] init]; 
[oldID release]; 

和:

// (nonatomic, retain) property is declared for myMemberVariable in interface 
self.myMemberVariable = [[MyMemberVariable alloc] init]; 

谢谢!

回答

4

第二个在技术上是不正确的,但第一个可能源于某人尚未拥抱Objective-C 2.0属性语法。如果您是一位长期的OS X开发人员(或者甚至是更长时间的NextStep/OS X开发人员),那么最近添加了这个功能,所以您确实看到人们在没有获得任何好处或不利的情况下不会使用它。

所以第一个是基本相同:

[myMemberVariable release]; 
myMemberVariable = [[MyMemberVariable alloc] init]; 

假设你有一个“保留”属性,正确版本的制定者应该是:

// this'll be retained by the setter, so we don't want to own what we pass in 
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease]; 
3

在第一个例子中,你有一个实例变量。第二种是具有自动内存管理属性的属性(如保留所示)。

在第一个示例中,您将分配一个对象,将其分配给一个实例变量,然后释放它。由于您没有明确释放它,因此您似乎也泄露了以前分配给它的对象。 (也许它是autoreleased,不能告诉这里)。

在第二个示例中,您将分配一个对象并将其分配给保留该对象的属性。这意味着你会泄漏它,除非你明确地释放/ autorelease它。

self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease]; 

MyMemberVariable *m = [[MyMemberVariable alloc] init]; 
self.myMemberVariable = m; 
[m release]; 

这是更好的为你(大部分)的内存管理的免费使用性质。例如,在分配新参考资料之前,您不必担心释放参考资料。

1

第一种形式呢不使用属性。我没有看到一个很好的理由不这样做:

[myMemberVariable release]; 
myMemberVariable = [[MyClass alloc] init]; 

由于旧的价值肯定是不一样的新,所以没有机会,才可以再次被保存的任何旧值被释放。

属性的优点是,在较新的编译器中,它们由编译器合成并简单地做正确的事情,即他们知道如何保留新的并释放旧值,如果该类型是必须保留的类型或复制。这对int,float等类型不是必需的,因为这些是简单的值类型。

换句话说,如果您使用点符号,无论是在自己还是在其他对象上,都可以访问该属性,实际上根据赋值方向调用getter或setter方法。

如果您直接访问ivar(成员变量),那么您不具有该属性的保护,并且必须自己编写保留/释放代码。

你也可以编写你自己的setters和getters,然后你也必须照顾内存管理,它适用。不过,它确实给你更多的灵活性。您可以记录项目,检查输入的有效性,更新内部状态变量等。