什么是内存?
程序运行时临时分配的存储空间,在程序结束后释放;
内存管理?
软件运行时对内存资源的分配和使用的技术。
对象的生命周期
对象的初始化(alloc和new) ——>执行,使用 ——>释放
引用计数(retaincount)
cocoa采用引用技术的技术来确定对象的生命周期结束。
alloc(引用计数置为1) retain(引用计数加1) release(引用计数减1)
内存管理原则:
1,任意对象在使用前必须alloc
2,每一个alloc,必须对应一个release或者autorelease
3,每一个retain,必须对应一个release或者autorelease
4,不能使用引用计数为0的对象
5,每一个对象在使用完毕后必须销毁
6,尽量保证在使用完毕后立即销毁对象
7,常量的引用计数为正无穷(即所有常量不需要内存管理内存)
// Person.h
// 5.22.oc.arc
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
NSString *_name;//setter ,getter 方法,成员变量加下划线
NSInteger _age;
NSArray *_score;
}
- (void)setName:(NSString *)name1;
- (void)setAge:(NSInteger)age1;
- (void)setScore:(NSArray *)score1;
- (NSString *)name1;
- (NSInteger)age1;
- (NSArray *)score1;
//自定义初始化
- (instancetype)initWithName:(NSString *)name2 andAge:(NSInteger)age2 andScore:(NSArray*)score2;
+ (Person *)personWithName:(NSString *)name3 andAge:(NSInteger)age3 andScore:(NSArray *)score3;
@end
// Person.m
// 5.22.oc.arc
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import "Person.h"
@implementation Person
- (void)setName:(NSString *)name1{
if (_name != name1) {//判断新传的是否和旧的相同
[_name release];//释放旧的
_name = [name1 retain];//保证一定拿到新的对象
}
/*另一种set方法的内存管理方法
[_name release];
[_name retain];
_name =name1;*/
}
//get不需要进行内存管理
- (void)setAge:(NSInteger)age1{
_age = age1;
}
- (void)setScore:(NSArray *)score1{
if (_score != score1) {
[_score release];
_score = [score1 retain];
}
_score = score1;
}
- (NSString *)name1{
return _name;
}
- (NSInteger)age1{
return _age;
}
- (NSArray *)score1{
return _score;
}
//自定义初始化方法内存管理
- (instancetype)initWithName:(NSString *)name2
andAge:(NSInteger)age2
andScore:(NSArray*)score2
{
self = [super init];
if (self) {
_name = [name2 retain];
_age = age2;
_score = [score2 retain];
}
return self;
}
//便利构造器内存管理
+ (Person *)personWithName:(NSString *)name3
andAge:(NSInteger)age3
andScore:(NSArray *)score3
{
Person *person = [[Person alloc] initWithName:name3 andAge:age3 andScore:score3];
return [person autorelease];
}
//成员变量一次性清除
- (void)dealloc
{
NSLog(@"person dealloc");
[super dealloc];
}
@end
// main.m
// 5.22.oc.arc
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
#pragma mark - 普通状态下的内存管理
Person *person = [[Person alloc] init];
NSLog(@"%ld",person.retainCount);//1
[person retain];
NSLog(@"%ld",person.retainCount);//2
[person retain];
NSLog(@"%ld",person.retainCount);//3
[person release];
NSLog(@"%ld",person.retainCount);//2
[person release];
NSLog(@"%ld",person.retainCount);//1
[person release];
NSLog(@"%ld",person.retainCount);//1 系统其实当作0处理的
// person = nil;//防止野指针
#pragma mark - 内存管理的原则
/*常见的内存区域
堆:需要的时候分配内存,不需要的时候手动释放,编译器不负责释放改区域的内存空间 nsstring
栈:需要的时候分配内存,不需要的时候自动释放,编译器负责释放改区域的内存空间 nsinteger
全局/静态存储区:存储全局变量和静态变量
常量存储区:存储常量,不可变的数据
自由存储区*/
/*1.使用alloc(创建内存,是需要释放的),new,copy,mutableCopy生成的对象 对象初始引用计数值为1,手动释放内存(堆上的对象)
2.便利初始化生成的对象,对象初始引用计数值为1,并且设置为自动释放,无需手动释放(栈上的对象)
3.使用retain持有的对象,需要保证retain和release次数相等*/
Person *person = [[Person alloc]init];
[person setName:@"jh"];
NSArray *score = [[NSArray alloc]initWithObjects:@"1", nil];
NSLog(@"%ld",score.retainCount);//1
[person setScore:score];
NSLog(@"%ld",score.retainCount);//2
[score release];
//[person release];//0 , dealloc调用,对象的销毁,内存的回收
NSLog(@"%ld",person.retainCount);
#pragma mark - 自定义初始化方法
NSArray *score = [[NSArray alloc] initWithObjects:@"1", nil];
NSLog(@"%ld",score.retainCount);//1
Person *person = [[Person alloc] initWithName:@"i" andAge:23 andScore:score];
NSLog(@"%ld",score.retainCount);//2
[score release];//创建的时候等于1,
[person release];
#pragma mark - 集合内存管理 数组字典
/*1.对象加入集合对象,+1
2.对象从集合对象中移除,-1
3.集合对象的retaincount改变,其中元素的retaincount不变
4.集合对象销毁时,其中所有的元素release一次*/
Person *person1 =[[Person alloc]init];
NSLog(@"%ld",person1.retainCount);//1
NSArray *array = [[NSArray alloc]initWithObjects:person1,nil];
NSLog(@"%ld",person1.retainCount);//2
[array retain];
NSLog(@"%ld,%ld",person1.retainCount,array.retainCount);//2
[array release];
NSLog(@"%ld,%ld",person1.retainCount,array.retainCount);//array 其实是0
[array release];
NSLog(@"%ld,%ld",person1.retainCount,array.retainCount);
[array retain];
NSLog(@"%ld,%ld",person1.retainCount,array.retainCount);
#pragma mark -自动释放池
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc]init];
Person *person2 =[[Person alloc]init];
[person2 retain];
NSLog(@"%ld",person2.retainCount);//2
[person2 autorelease];//滞后减一,所以不会变
NSLog(@"%ld",person2.retainCount);//2
[person2 autorelease];
NSLog(@"%ld",person2.retainCount);//2
[pool release];//倾倒释放池,才会开始减,所有对象都release
NSLog(@"%ld",person2.retainCount);//显示为1,实际为0
NSArray * array = [NSArray arrayWithObjects:@"f",nil];
NSArray * array1 = [[[NSArray alloc] initWithObjects:@" ", nil]autorelease];
#pragma mark -便利构造内存管理
NSArray *score = [[NSArray alloc] initWithObjects:@"1", nil];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
Person *person =[Person personWithName:@"jiangh" andAge:21 andScore:score];
NSLog(@"%ld",person.retainCount);
[pool release];
NSLog(@"%ld",person.retainCount);
#pragma mark - 快速生成(便利构造,不需要内存管理)
// NSArray *array = @[@"ggg",@"awe"];
}
return 0;
}
一个题:
/*
* 1、创建一个Student类,包含姓名(name)、性别(gender)、年龄(age),另外还包含一个数组类型的课程内容(NSArray * lessons);
* 1)写出自定义初始化方法和便利构造器初始化方法;(注意:方法中的参数只有姓名、性别、年龄);
* 2)写出lessons的setter()方法;
* 3)在main函数中,使用初始化方法,创建3个Student对象,使用点语法对lessons赋值;
* 4)注:每个地方的内存管理问题和dealloc方法;
*/
/*
* 2、创建一个Teacher类,包含姓名(name)、多名学生(NSArray * students);
* 1)分别写出特性的setter()方法;在main函数中创建teacher对象,使用点语法进行调用赋值;
* 2)书写一个自定义方法print(),并调用该方法;
* 3)注意:每个地方的内存管理问题;
*/
// main.m
// L05--内存管理
//
// Created by liwenyu on 14/12/17.
// Copyright (c) 2014年 liwenyu. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Teacher.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
// NSLog(@"Hello, World!");
/*
* 1、创建一个Student类,包含姓名(name)、性别(gender)、年龄(age),另外还包含一个数组类型的课程内容(NSArray * lessons);
* 1)写出自定义初始化方法和便利构造器初始化方法;(注意:方法中的参数只有姓名、性别、年龄);
* 2)写出lessons的setter()方法;
* 3)在main函数中,使用初始化方法,创建3个Student对象,使用点语法对lessons赋值;
* 4)注:每个地方的内存管理问题和dealloc方法;
*/
/*
* 2、创建一个Teacher类,包含姓名(name)、多名学生(NSArray * students);
* 1)分别写出特性的setter()方法;在main函数中创建teacher对象,使用点语法进行调用赋值;
* 2)书写一个自定义方法print(),并调用该方法;
* 3)注意:每个地方的内存管理问题;
*/
NSArray * array1 = @[@"english", @"math", @"chinese"];
Student * student1 = [Student studentWithName:@"zhangsan" gender:@"nan" age:12];
[student1 setLessons:array1];
NSArray * array2 = [[NSArray alloc] initWithObjects:@"english", @"chinese", @"math", nil];
Student * student2 = [[Student alloc] initWithName:@"zhangsi" gender:@"nsn" age:12];
[student2 setLessons:array2];
NSArray * array3 = @[@"english"];
Student * student3 = [[Student alloc] initWithName:@"zhangwu" gender:@"nan" age:19];
[student3 setLessons:array3];
Teacher * teacher = [[Teacher alloc] init];
NSArray * students = [[NSArray alloc] initWithObjects:student1, student2, student3, nil];
[teacher setStudents:students];
[teacher print];
[array2 release];
[student2 release];
[student3 release];
[teacher release];
[students release];
// 内存管理
/*
* array1 、 student1 、array3 为便利构造器初始化方法创建的对象,不需要管理内存
*/
}
return 0;
// Teacher.m
// 5.22.OC.HW
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import "Teacher.h"
@implementation Teacher
- (void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name retain];
}
}
- (NSString *)name
{
return _name;
}
- (void)setStudent:(NSArray *)student
{
if (_student != student) {
[_student release];
_student = [student retain];
}
}
- (NSArray*)student
{
return _student;
}
- (void)print
{
NSLog(@"print");
}
- (void)dealloc
{
[_student release];
[_name release];
[super dealloc];
}
@end
// Teacher.h
// 5.22.OC.HW
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Teacher : NSObject
{
NSString *_name;
NSArray * _student;
}
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setStudent:(NSArray *)studnet;
- (NSArray*)student;
- (void)print;
@end
// Student.h
// 5.22.OC.HW
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
NSString *_name;
NSInteger _age;
NSString *_gender;
NSArray *_lesson;
}
- (void)setLesson:(NSArray *)lesson;
- (NSArray *)lesson;
//自定义初始化方法
- (instancetype)initWithName:(NSString *)name
andAge:(NSInteger)age
andGender:(NSString *)gender;
//便利构造器方法
+ (Student *)studentWithName:(NSString *)name
andAge:(NSInteger)age
andGender:(NSString *)gender;
@end
// Student.m
// 5.22.OC.HW
//
// Created by rimi on 15/5/22.
// Copyright (c) 2015年 rectinajh. All rights reserved.
//
#import "Student.h"
@implementation Student
- (void)setLesson:(NSArray *)lesson
{
if (_lesson != lesson) {
[_lesson release];//释放旧的
_lesson = [lesson retain];//保证拿到新的对象
}
}
- (NSArray *)lesson
{
return _lesson;
}
//自定义初始化方法
- (instancetype)initWithName:(NSString *)name
andAge:(NSInteger)age
andGender:(NSString *)gender
{
self = [super init];
if (self) {
_name = name;
_age = age;
_gender = gender;
}
return self;
}
//便利构造器方法
+ (Student *)studentWithName:(NSString *)name
andAge:(NSInteger)age
andGender:(NSString *)gender
{
Student *student = [[Student alloc] initWithName:name andAge:age andGender:gender ];
return [student autorelease] ;
}
- (void)dealloc
{
NSLog(@"请注意!成员变量已经一次性清除");
[super dealloc];
}
@end