内存管理是每个程序员必须要掌握的技能, 也是写好一个程序,写一个好程序的必备技能. 下面谈一下我对iOS开发中的内存管理的理解.
如果你是一个比较新的iOS程序员, 那么恭喜你, 你已经很轻松了, 因为在现在的开发中已经很少去手动管理内存了, 那么问题来了, 既然不需要去手动管理了那学他还有什么用呢? 当然有用, 因为之后你学了之后才会真正了解一个对象的创建和消失过程. 而且对于比较老的第三方框架来说很多还是用的手动内存管理, 所以学好手动内存管理也是读懂第三方框架的基础. 对于有些较老的项目, 通常也是采用的手动内存管理, 如果想去维护也必须要学会手动内存管理.
对于初学者, 听到内存管理就会有一种畏惧感, 其实对于OC来说很多底层的实现官方已经帮我们封装好了, 所以我们要做的管理只有两件事情, 第一就是内存泄露, 第二就是野指针. 简单的说内存泄露就是指向对象的指针已经没了, 但是这个对象依然在内存里存在, 无法释放, 当这样的对象达到一定程度, 就会引起内存泄漏. 当对象释放了, 而指向对象的指针中依然存着指向对象的地址, 再次对这个指针操作时,就会出问题, 这也是常说的僵尸对象.
内存管理遵循以下原则. 只要出现了 new,alloc,retain,引用计数retainCount就会加1, 因此就一定配对出现一个release, 原则就是在哪里创建就在哪里release , 这样就不容易出现遗漏. 对于多个对象相互引用的情况直接用代码说明吧.
// main.m
// 手动内存管理
// Created by apple on 14-4-14.
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Person * p = [[Person alloc] init];
Car * c1 = [[Car alloc] init];
c1.speed = 100;
[p setCar:c1];
[p drive];
[c1 release];
Car * c2 = [[Car alloc] init];
c2.speed = 350;
[p setCar:c2];
[p drive];
[c2 release];
[p release];
}
return 0;
}
// Car.h
// 手动内存管理
// Created by apple on 14-4-14.
#import <Foundation/Foundation.h>
@interface Car : NSObject
@property int speed;
- (void)run;
@end
// Car.m
// 手动内存管理
// Created by apple on 14-4-4.
#import "Car.h"
@implementation Car
- (void)dealloc{
[superdealloc];
NSLog(@"Car被销毁了 %d速度",_speed);
}
- (void)run{
NSLog(@"汽车run");
}
@end
// Person.h
// 手动内存管理
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
{
Car * _car;
NSString * _name;
}
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setCar:(Car *)car;
- (Car *)car;
- (void)drive;
@end
// Person.m
// 手动内存管理
#import "Person.h"
//配对原则:new alloc retain对应一个release,autorelease
@implementation Person
- (void)setName:(NSString *)name
{
if (_name != name)
{
[_namerelease];
_name = [nameretain];
}
}
- (NSString *)name
{
return_name;
}
- (void)setCar:(Car *)car
{
if (_car != car)
{
//relese旧值
[_carrelease];//[nil release];
//retain新值
_car = [carretain];
}
}
- (Car *)car
{
return_car;
}
- (void)drive
{
[_carrun];
}
- (void)dealloc
{
//目的是要保证在p对象存在的时候,car对象一定存在
//对象p被销毁的时候,
[_carrelease];
[_namerelease];
[superdealloc];
NSLog(@"Person被销毁了");
}
@end
因为在person中存在一个car对象, 所以在person销毁时需要对car对象进行销毁, 所以在 person类的dealloc方法中要对car进行release操作, 这样才能保证所有对象都被正确释放.