您的位置:首页 > 其它

OC基础语法学习5:内存管理(手动管理)

2015-06-02 13:12 465 查看
1、一个对象的创建的过程:

[[类 alloc]init];

1、先分配内存空间,存储对象
2、初始化成员变量
3、返回对象的指针地址


对象在创建的同时,内部会自动创建一个引用计数器,这个引用计数器是系统用来判断对象回收的唯一依据。当引用计数器为retainCount = 0时,系统会自动调用dealloc函数,将对象销毁。

[对象 retain]; // retainCount + 1
[对象 release]; //retainCount - 1


2、内存管理的原则:

只要出现了new alloc retain就一定要有对应的 release autorelease 出现。


3、手动内存管理研究的主要问题:

1、野指针操作:是指该指针指向的内存空间已经不存在了,该指针也没有赋值为 nil,对该指针继续进行操作。
2、内存泄漏:不再使用的对象一直存在内存中。


4、避免野指针操作的方法:

内存空间释放完毕之后的指针一定要赋值为 nil


5、避免内存泄漏的操作方法:

遵守内存管理的配对原则。


例子:

.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (void)run;

@end


.m文件

#import "Person.h"

@implementation Person
//该函数在对象接到release消息时由系统自动调用的
-(void)dealloc
{
//在对象自身被销毁之前,一定要先调用[super dealloc]释放父类中的相关对象
[super dealloc];
NSLog(@"Person 被销毁了");
}

- (void)run
{
NSLog(@"人跑起来了");
}
@end


main.m

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

// 1
Person * p = [[Person alloc] init];

NSLog(@"%lu",p.retainCount);

// 2
[p retain];

NSLog(@"%lu",p.retainCount);

// 1
[p release];

NSLog(@"%lu",p.retainCount);

//0
[p release];
p = nil;

}


6、set方法的内存管理分析

car.h

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property int speed;

- (void)run;

@end


Car.m

#import "Car.h"

@implementation Car

- (void)dealloc
{
[super dealloc];
NSLog(@"Car 被销毁了 %d速度",_speed);
}

- (void)run
{
NSLog(@"汽车跑起来了");
}

@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)
{
[_name release];
_name = [name retain];
}

}
- (NSString *)name
{
return _name;
}
//面试笔试,出题率非常高
- (void)setCar:(Car *)car
{

if (_car != car)
{
[_car release];  //第一个Car对象进入是执行[nil release];
_car  = [car retain];
}

}
- (Car *)car
{
return _car;
}

- (void)drive
{
[_car run];
}
- (void)dealloc
{
//目的是要保证在p对象存在的时候,car对象一定存在
[_car release];
[_name release];
[super dealloc];
NSLog(@"Person 被销毁了");
}

@end


7、@property参数的内存管理分析

7.1、@property 的3个作用:

- 生成set与get方法的声明
- 生成set与get方法的简单实现
- 如果没有相对应的成员变量,会自动生成_开头的成员变量


7.2、@property参数分为4类

1、与set方法内存管理相关的参数
retain:要生成符合内存管理原则的set方法(应用于对象)
@property (nonatomic,retain) Car* car;
assign: 直接赋值(对象类型,基本数据类型)
@property (nonatomic,assign) int age;
copy:拷贝

2、多线程相关
nonatomic:不生成多线程管理代码,(效率高)
@property (nonatomic ,retain) NSString * name;
atomic:生成多线程管理代码(不写默认就是这种方式)
实际开发中都用nonatomic
3、是否要生成set与get方法
readwrite:可读可写属性,同时生成set和get方法
readonly:只读属性,只生成get方法
@property (nonatomic,assign,readonly)int idCard;
4、set与get方法名称相关的参数
setter:设置生成的setter方法名称
getter:设置生成的get方法名称
@property (nonatomic,assign,setter = isDeid:,getter = isDeid)BOOL isDeid;


注意:

如果一个对象被生成了成员变量或者使用了@property生成了符合setter的内存管理方法,那么在dealloc函数对应一次release的操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oc