Objective-C introduction - 5

去我的目录

iPhone 程序开发时内存的管理

 

在开发iPhone 程序时,一定要特别小心内存的管理。其实基本的道理很简单,就像我们以前写C++ 程序一样,newdelete 要成对出现。问题是在某些时候,我们没有意识到自己使用了new

 

Objective-C 中对内存的管理采用引用计数的技术。简单说就是,当我们拥有一个变量的时候,这个变量的计数就加1,当我们释放这个变量的时候,这个变量的计数就减1。当计数为0时,这个变量就可以合法的被删除了。

 

1)alloc 很明显,这个函数调用之后,变量的计数加1。所以在调用alloc 之后,一定要调用对应的release

2)retain 保留一个对象。调用之后,变量的计数加1。或许不是很明显,我们举个例子

- (void) setName : (NSString*) name {

     [name retain];

     [myname release];

     myname = name;

}

 

我们来解释一下:设想,用户在调用这个函数的时候,他注意了内存的管理,所以他小心的写了如下代码:

NSString * newname = [[NSString alloc] initWithString: @"John"];

[aClass setName: newname];

[newname release];

 

我们来看一看newname的计数是怎么变化的。首先,它被alloc,count = 1; 然后,在setName中,它被retain, count = 2; 最后,用户自己释放newname,count = 1,myname指向了newname。这也解释了为什么需要调用[myname release]。我们需要在给myname赋新值的时候,释放掉以前老的变量。

3)copy 返回某个对象的一个拷贝。这个拷贝是一个新的对象,它的计数为1,需要在将来被release。

 

基本上,所有带有alloc, retain, copy的函数,都会使得变量的计数加1。因此在调用完这些方法之后,要小心release。另外还有一些初始化函数,它们没有带有alloc , retain 或者copy 的字样,比如stringWithFormat ,它们并不会使变量计数加1。

 

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

<script type="text/javascript"> </script> <script type="text/javascript"> </script>

Autorelease

在Objective-C中,这个概念很象Java中的Garbage Collection 。它会把内存的管理交给另一个系统(autorelease pool)。在某些时候,我们在一个函数内部创建(alloc )了一个变量,但是我们无法在函数内部将这个变量释放(确实会有这种情况出现。。。),而显然,我们不可能在函数外部释放这个变量,这时候就可以借助Autorelease来帮忙了。据说,我们应该尽量自己管理内存,不要随便交给Autorelease。天下没有免费的午餐啊,呵呵。自己省了事,但是也失去了对内存的控制。。。天知道autorelease pool啥时候才会给你release啊。。。

 

 

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

 

Objective-C 提供了一些容器,如NSArray , NSDictionary , NSSet 等等,加入容器的对象都会使计数加1。这和C++ 中的容器类很相似。我们在C++ 中,常常看到:

void addElement( vector<ClassA>& my_list; )

{

    ClassA object1;

    my_list.push_back(object1);

}

虽然object1 是一个临时变量,在函数调用结束后会自动销毁,我们仍然可以安全的添加元素。

所以在Objective-C 中,我们也能看到如下代码:

NSMutableArray * array = [[NSMutableArray alloc] init];

NSNumber *num = [[NSNumber alloc] initWithInt: 1];

[array addObject: num ];

[num release];

... ...

 

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

再看两个编码上可以考量的地方:

1)为什么我们很少看见有人这样写代码:

AClass * class = [AClass alloc];

[class init];

而基本上都是 AClass * class = [[AClass alloc] init];

原因很简单,因为我们需要确保当init 调用失败的时候,class是一个无效的值(nil)。如果使用第一种方式,我们无法通过class的值知道init是否调用成功。这也告诉我们,在实现自己的init 方法时,需要在失败的时候返回nil

2)一般在dealloc方法中,我们都会释放一些变量,所以我们经常看到

- (void) dealloc {

    [ var release];

    [ super dealloc];

}

这样写当然没有错,但是我看见过某些“geek ”分析到:

在调用release 之后,虽然变量被释放了,可是它的值仍然是有效的。就好像我们在C++ 里面,delete 一个变量之后,一个好的习惯是,接着将这个变量赋值为0。所以,最优的方法是加上var = nil;

 

以上就是一些使用Objective-C 需要注意的地方。

 

到这里,我基本上说完了关于Objective-C 的基础内容,当然,它本身还有很多东西,不可能通过短短几篇博客就说完。而且我使用Objective-C 的时间也不长,无法做到面面俱到。但是,个人认为掌握这些基本概念之后,我们就可以开始iPhone 程序的开发了,在开发的过程中继续加深对Objective-C 的理解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值