您的位置:首页 > 移动开发 > IOS开发

整理一些关于IOS内存管理的东西,希望对大家有帮助

2014-08-18 11:18 375 查看
【基本的内存管理规则】

内存管理模式基于对象的“所有权”上。任何对象都会被有一个或多个使用者引用,只要对象还有一个使用者,该对象就应该继续存在。如果一个对象没有使用者了,系统将自动销毁它。为了让开发者清晰的了解:使用对象和不再使用对象的场景,Cocoa设置了以下策略:

1.管好自己创建的对象。开发者使用alloc、new、copy和mutableCopy来创建对象。

2.使用retain来获得对象的所有权。某个函数接受的对象,通常保证在该函数调用期间仍然可用,并可以安全返回对象给上层调用者。开发者在以下两种情况下使用retain

1)在“访问函数”(accessor)的实现中或者在init方法,为了将对象作为自己的属性。

2)防止对象被其他操作释放掉,从而变为无效的对象。

3.当你不在需要的时候,必须放弃对象所有权。

一个简单的例子

看看下面的代码段,可以证明刚刚的所说的策略
{
Person *aPerson = [[Person alloc] init];
// ...
NSString *name = aPerson.fullName;
// ...
[aPerson release];
}


Person被通过alloc创建之后,当Person不在使用的时候,发送了一个release的消息。name这个变量没有使用,所以name不必发送release消息。

使用autorelease来发送一个延迟的release

典型的使用场景:函数返回一个对象的时候。例如,你可以像这样实现fullName的方法:
- (NSString *)fullName {
NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",
self.firstName, self.lastName] autorelease];
return string;
}


上面就是典型的场景:你想放弃对象的所有权,但是又想让调用者在string销毁前使用返回值。

还可以通过下面的实现达到上面的效果:
- (NSString *)fullName {
NSString *string = [NSString stringWithFormat:@"%@ %@",
self.firstName, self.lastName];
return string;
}


根据命名惯例,full name方法不具备返回值的所有权。因此,调用者无需对返回值string进行release

【系统执行dealloc时间间隔的问题】

大家都知道在ios编程过程中,当一个变量的引用计数变为零的的时候此时retaincount输出他的引用计数会发现是1,像这样

输出引用计数结果为1
[class16 release];
NSLog(@"%ld", [class16 retainCount]);


但是这种情况通常是在对该对象调用release方法后紧接着跟一个NSlog输出他的引用计数, 但是如果你后面接两行同样的NSlog输出的他的引用计数的话或者更多行的时候他会出现崩溃,不过一个很有趣的现象就是崩溃所在的行数是不一定的

大家注意看崩溃时所在的行数

我们会发现他会存在一个随机性,大家知道当一个对象的引用计数为0的时候,程序会自动调用dealloc函数将其销毁,如果销毁之后你再对其进行任何操作都会崩溃,就像上图那样,但是系统调用dealloc函数和我们自己写的NSlog输出函数会存在一个时间先后的问题,这也就是我们运行结果随机性的根源,如果你的NSlog在系统调用dealloc之前被调用,那么就会正常显示1,如果在其之后那么就会崩溃,打个比方假如系统在计数变为零后一秒后调用dealloc,那么在这一秒之内所有的对其操作都会有显示,一旦一秒过了就会产生崩溃,而具体是多长时间之后才调用,这取决你系统本身,代码量以及很多因素,那么我由此想到,即使第一种情况只有紧接着一行的NSlog也不一定是百分之百可以成功的,对此我试了执行100次其中有8次会产生崩溃,几率是很小的,但是也证明了不是百分之百能成功的,我说这个也就是希望大家明白一下内存管理的机制

【实现dealloc放弃对象的所有权】

NSObject类定义了一个方法dealloc,当某个对象没有使用者,并它的内存是可再生的,delloc就自动被调用。delloc的角色就是释放对象占用的内存并且处理自己所拥有的资源,包括本身变量的释放。

下面的代码展示了,如何实现Person类的dealloc函数。
@interface Person : NSObject
@property (retain) NSString *firstName;
@property (retain) NSString *lastName;
@property (assign, readonly) NSString *fullName;
@end

@implementation Person
// ...
- (void)dealloc
[_firstName release];
[_lastName release];
[super dealloc];
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐