首页 > 图灵资讯 > 技术篇>正文

Objective-C内存管理

2023-05-04 10:35:12

对于我们.对Net开发人员来说,.net为我们提供了一种自动内存管理机制,我们不需要关心内存管理。但iPhone开发是不可能的。本文将简要介绍objective-c的内存管理机制、方法和一些特点。

手动管理内存

Cocoa和Objective-C类是NSObject的子类。内存管理在NSObject中有几种方法。allloc方法为对象分配内存空间。用于释放对象空间的dealloc方法。但是dealloc永远不会用于我们的代码,因为它会在操作过程中为您调用此方法来释放内存空间。你所需要做的就是引用计数,然后介绍什么是引用计数。

除了alloc和dealloc,NSObject还有两种引用计数的方法:retain和release。retain方法给retainCount变量加1,release方法给retainCount变量减1。当使用alloc为对象分配一个内存空间时,retaincount将是1。在这个对象的生命周期中,这个对象可能会继续被其他变量引用。但是,当有一个新的变量指向这个对象时,你应该调用retain方法,这样你就会知道有一个新的引用指向这个变量,并有权在这个对象的生存期间使用它。Objective-c开发人员称之为“拥有”。例如:

1. * myFooOne= [[Foo alloc] init]; //retaincount 为1 2. 3. * myFooTwo= myFooOne; //myFooTwo 指向这个对象 4. 5. 仍然为1 6. 7. retain]; //调用retain方法,运行时才知道myFootwo指向对象,retaincount 为2

在上述代码中,myFootwo通过调用retain获得了Foo对象的所有权。在这个对象的生命周期中,会有很多变量来指向和引用它。这种所有权也可以通过release来解除指向这个对象的变量。release方法会告诉操作时,我已经用完了这个变量,不再需要了,retaincount计数减1。

当对象的retaincount计数大于或等于1时,该对象将在运行过程中继续保持。当对象的retaincount为0时,运行过程中会释放对象,并回收它占用内存空间。

下图显示了Fooo对象的生命周期。Foo对象首先在内存中分配一个内存空间,并被myFooone引用。此时,Fooo对象的retaincount为1。

Foo * myFooOne = [[Foo alloc] init];

 

第二个引用变量指向Fooo对象,然后调用retain方法,这实际上是调用foo对象的retain方法。Foo对象的retaincount变成2。

1. * myFooTwo= myFooOne; 2. 3. retain];

然后,当myFoone不需要引用时,通过调用release来解除与Fooo对象的所有权,Fooo对象的retaincount变成1。

1. release];

然而,当myFootwo不再需要时,它也通过调用release来解除与Foo对象的所有权,Foo对象的retaincount变成0。

内存泄露

我们经常以一种方式声明对象,看下面的例子:

1. myMethod { 2. 3. method 4. 5. * myString= [[NSString alloc] init]; //retainCount= 16. 7. * myFoo= [[Foo alloc] initWithName:myString]; //retainCount= 18. 9. Name:%@", [myFoo getName]); 10. 11.

在上述方法中,我们是myString 内存空间与myFoo分配。实施方法后,两个变量超出了作用域的范围,因此不再有效。但是这种方法没有releases这两个对象。因此,这两个变量占据的内存空间在运行过程中没有释放。除非你的应用程序结束,否则这两个变量所占用的内存空间总是不可用的。我们称之为内存泄漏。

为了防止内存泄漏。无论我们何时创建一个对象,或者创建一个对象的副本,我们都必须通过release释放它。

弱引用

1. myMethod { 2. 3. * myString= [[NSString alloc] init]; //retainCount=14. 5. * myFoo= [[Foo alloc] initWithName:myString]; //retainCount=16. 7. Name:%@", [myFoo getName]); 8. 9. release]; //retainCount=0so deallocate 10. 11. release]; //retainCount=0so deallocate 12.

看以下例子:

1. myMethod { 2. 3. incorrect method 4. 5. * myFooOne= [[Foo alloc] initWithName:@"James"]; //retainCount=16. 7. * myFooTwo= myFooOne; //retainCount still 1 8. 9. release]; //retaincount=0so deallocated 10. 11. [myFooTwo printOutName]); //runtime error 12.

nyFoootwo指向Foo对象,但如果不调用retain方法,则为弱引用,上述代码在运行时会出错。因为myFooone调用release方法。retaincount变为0,运行时回收对象的内存空间。然后myFootwo调用printputname自然报错

结论:本文简要介绍了Objective-C的手动内存管理、内存泄漏、弱引用等知识。

上一篇 高清版 SpringCloud与SpringBoot版本对应关系如何选择?
下一篇 动态规划之背包问题

文章素材均来源于网络,如有侵权,请联系管理员删除。