标签:
1 手动内存管理基本概念
创建对象
1.分配内存空间,存储对象
2.初始化成员变量
3.反回对象的指针地址
//1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系统会毫不犹豫回收当前对象
//2.[对象 release] reatinCount - 1
//3.[对象 retain] reatinCount + 1 ,返回self
//4.我们的引用计数retainCount = 0的 对象就被销毁了
//5.dealloc函数,当一个对象要被销毁的时候,系统会自动调用dealloc函数,通知对象你将要被销毁
//内存管理原则(配对原则):只要出现了 new,alloc,retain,就一定配对出现一个release,autorelease
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 9 // 1 10 Person * p = [[Person alloc] init]; 11 12 NSLog(@"%lu",p.retainCount); 13 14 // 2 15 [p retain]; 16 17 NSLog(@"%lu",p.retainCount); 18 19 // 1 20 [p release]; 21 22 NSLog(@"%lu",p.retainCount); 23 24 //0 25 [p release]; 26 27 } 28
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 -(void)dealloc 6 { 7 //在对象自身被销毁之前,一定要先调用[super dealloc]释放父类中的相关对象 8 [super dealloc]; 9 NSLog(@"Person 被销毁了"); 10 } 11 12 13 - (void)run 14 { 15 NSLog(@"人跑起来了"); 16 } 17 @end
Person.h
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 5 - (void)run; 6 7 @end
2 单个对象内存管理分析
Person.m
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject 3 @property int age; 4 - (void)run; 5 @end
Person.h
1 #import "Person.h" 2 @implementation Person 3 - (void)dealloc 4 { 5 [super dealloc]; 6 7 NSLog(@"Person 被销毁了"); 8 } 9 10 - (NSString *)description 11 { 12 return [NSString stringWithFormat:@"age = %d",_age]; 13 } 14 - (void)run 15 { 16 NSLog(@"人跑起来了"); 17 } 18 @end
main.m
1 // 2 //内存管理原则(配对原则):只要出现了 new,alloc,retain,就一定配对出现一个release,autorelease 3 //手动内存管理研究问题方法 4 //1.野指针操作 5 //2.内存泄漏 6 #import <Foundation/Foundation.h> 7 #import "Person.h" 8 void test() 9 { 10 //retainCount = 1 11 Person * p = [[Person alloc] init]; 12 13 p.age = 10; 14 NSLog(@"%@",p); 15 16 //retainCount = 0 17 //系统已经将p所指向的对象回收了 18 //EXC_BAD_ACCESS 访问了不可访问的内存空间 19 //被系统回收的对象我们称之为僵尸对象 20 //默认情况下xcode为了提高编码效率,不会时时检查僵尸对象 21 22 [p release]; 23 24 // NSLog(@"p所指向的对象回收了 %@",p); 25 // p.age = 20;//[p setAge:20]; 26 [p run]; 27 28 } 29 void test2() 30 { 31 Person * p = [[Person alloc] init]; 32 p.age = 20; 33 34 NSLog(@"%@",p); 35 36 [p release]; 37 //如果你确定当前作用于中的对象已经不会再被使用了,为了防止野指针操作,通常我们会把不在使用的指针变量赋值为nil 38 p = nil; 39 40 p.age = 30;//[nil setAge:30]; 41 [p run]; //[nil run]; 42 //避免野指针操作的方法 [nil resele] 43 44 } 45 void test3() 46 { 47 /* 48 //内存泄漏第一种情况 49 //1 50 Person * p = [[Person alloc] init]; 51 52 p.age = 20; 53 NSLog(@"%@",p); 54 //2 55 [p retain]; 56 57 //3 58 [p retain]; 59 60 //2 61 [p release]; 62 63 //只要对象的retainCount != 0 就会一直存在在内存中 64 //内存泄漏指的就是,不再被使用的对象,一直在内存中没有被销毁 65 */ 66 67 /* 68 //内存泄漏第二种情况 69 //retainCount = 1 70 Person * p = [[Person alloc] init]; 71 p.age = 20; 72 [p run]; 73 74 p = nil; 75 76 77 [p release];//[nil release]; 78 */ 79 80 //1 81 Person * p = [[Person alloc] init]; 82 83 p.age = 20; 84 [p run]; 85 86 Person * p1 = p; 87 88 //0 89 // [p release]; 90 [p1 release]; 91 92 //野指针操作 93 p1.age = 20; 94 95 } 96 void test4() 97 { 98 //1 99 Person * p = [[Person alloc] init]; 100 101 p.age = 20; 102 NSLog(@"%@",p); 103 104 //0 105 [p release]; 106 107 //野指针操作,当一个对象retainCount已经为0 时,调用retain方法,是不会使得对象起死回生的,同时还会发生野指针操作异常 108 [p retain]; 109 } 110 111 void test5(Person * p) 112 { 113 p.age = 30;// release retain 114 [p retain]; //2 115 // [p release]; 116 NSLog(@"%@",p); 117 } 118 119 int main(int argc, const char * argv[]) 120 { 121 122 @autoreleasepool { 123 124 //1 125 Person * p = [[Person alloc] init]; 126 p.age = 20; 127 128 // test5(p); 129 //1 130 [p release]; 131 //0 132 [p release]; 133 134 } 135 return 0; 136 }
3 多个对象的内存管理分析
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 - (void)setCar:(Car *)car 6 { 7 //2,能够使得retainCount + 1 并且返回self 8 _car = [car retain]; 9 10 } 11 - (Car *)car 12 { 13 return _car; 14 } 15 16 - (void)drive 17 { 18 [_car run]; 19 } 20 - (void)dealloc 21 { 22 //目的是要保证在p对象存在的时候,car对象一定存在 23 //对象p被销毁的时候, 24 [_car release] 25 [super dealloc]; 26 NSLog(@"Person 被销毁了"); 27 } 28 29 @end
Person.h
1 #import <Foundation/Foundation.h> 2 #import "Car.h" 3 4 @interface Person : NSObject 5 { 6 Car * _car; 7 } 8 9 - (void)setCar:(Car *)car; 10 - (Car *)car; 11 12 - (void)drive; 13 14 @end
Car.m
1 #import "Car.h" 2 3 @implementation Car 4 5 - (void)dealloc 6 { 7 [super dealloc]; 8 NSLog(@"Car 被销毁了"); 9 } 10 11 - (void)run 12 { 13 NSLog(@"汽车跑起来了"); 14 } 15 16 @end
Car.h
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 5 - (void)run; 6 7 @end
main.m
1 #import <Foundation/Foundation.h> 2 3 //人拥有一辆汽车 4 #import "Person.h" 5 6 7 //1.野指针问题 8 //2.内存泄漏问题 9 int main(int argc, const char * argv[]) 10 { 11 12 @autoreleasepool { 13 14 // 1 15 Person * p = [[Person alloc] init]; 16 17 // 1 18 Car * car = [[Car alloc] init]; 19 20 //2 21 [p setCar:car]; 22 23 [p drive]; 24 25 26 //1 27 [car release]; 28 29 //要保证对象p 存在的时候,调用对象p的任何方法都不会出错 30 [p drive]; 31 32 //0 33 [p release]; 34 35 } 36 return 0;
4 set方法的内存管理分析
Person.m
1 #import "Person.h" 2 3 //配对原则:new alloc retain 对应一个release,autorelease 4 5 @implementation Person 6 7 - (void)setName:(NSString *)name 8 { 9 if (_name != name) 10 { 11 [_name release]; 12 _name = [name retain]; 13 } 14 15 } 16 - (NSString *)name 17 { 18 return _name; 19 } 20 - (void)setCar:(Car *)car 21 { 22 23 if (_car != car) 24 { //c1 0 25 //relese旧值 26 [_car release];//[nil release]; 27 //c2 2 28 //retain新值 29 _car = [car retain]; 30 } 31 32 } 33 - (Car *)car 34 { 35 return _car; 36 } 37 38 - (void)drive 39 { 40 [_car run]; 41 } 42 - (void)dealloc 43 { 44 //目的是要保证在p对象存在的时候,car对象一定存在 45 //对象p被销毁的时候, 46 //0 47 //c2 0 48 [_car release]; 49 [_name release]; 50 [super dealloc]; 51 NSLog(@"Person 被销毁了"); 52 } 53 54 @end
Person.h
1 #import <Foundation/Foundation.h> 2 #import "Car.h" 3 4 @interface Person : NSObject 5 { 6 Car * _car; 7 NSString * _name; 8 } 9 10 - (void)setName:(NSString *)name; 11 - (NSString *)name; 12 13 - (void)setCar:(Car *)car; 14 - (Car *)car; 15 16 - (void)drive; 17 18 @end
Car.m
1 #import "Car.h" 2 3 @implementation Car 4 5 - (void)dealloc 6 { 7 [super dealloc]; 8 NSLog(@"Car 被销毁了 %d速度",_speed); 9 } 10 11 - (void)run 12 { 13 NSLog(@"汽车跑起来了"); 14 } 15 16 @end
Car.h
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 5 @property int speed; 6 7 - (void)run; 8 9 @end
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 9 //p 1 10 Person * p = [[Person alloc] init]; 11 12 // c1 1 13 Car * c1 = [[Car alloc] init]; 14 c1.speed = 100; 15 16 //c1 2 17 [p setCar:c1]; 18 19 [p drive]; 20 21 //c1 1 22 [c1 release]; 23 24 25 /* 26 [p setCar:c1]; 27 [p drive]; 28 */ 29 30 31 //c2 1 32 Car * c2 = [[Car alloc] init]; 33 c2.speed = 350; 34 35 //c2 2 36 [p setCar:c2]; 37 38 39 [p drive]; 40 41 //c2 1 42 [c2 release]; 43 44 45 //p 0 46 [p release]; 47 48 } 49 return 0; 50 }
5@property参数
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 - (void)dealloc 6 { 7 //如果一个对象被生成成了成员变量或者是使用@property生成的符合内存管理的set方法,那么一定要在 dealloc函数对应一次release操作 8 [super dealloc]; 9 [_car release]; 10 NSLog(@"Person 被销毁了"); 11 } 12 13 @end
Person.h
1 #import <Foundation/Foundation.h> 2 #import "Car.h" 3 @interface Person : NSObject 4 5 //1.生产get与set方法的声明 6 //2.生成get与set方法的简单实现 7 //3.若果你没有声成名相对象的成员变量,那么他会自动生成一个_开头的成员变量 8 9 //@property 参数分为4类 10 /* 11 1.与set方法内存管理相关参数 12 retain: 要生成符合内存管理原则的set方法(应用与对象类型) 13 assign: 直接赋值,(对象类型,基本数据类型) 14 copy : (后面讲解) 15 */ 16 17 //2.多线程相关 18 //nonatomic: 不生成多线程线管代码,使用这个就可以了(效率高一点) 19 //atomic:生成多线程线管代码(不写默认是这种方式) 20 //实际开发中,只要是对象类型的@property都写成下面 21 22 //3.是否要生成set与get方法 23 //readwrite: 可读可写属性,同时生成set与get方法 24 //readonly : 只读属性,只生成get方法 25 26 //4.set与get方法名称相关的参数 27 //setter:设置生成的set方法名称 28 //getter:设置生成的get方法名称 29 30 @property (nonatomic,retain) Car * car; 31 @property (nonatomic,retain)NSString * name; 32 @property (nonatomic,assign)int age; //int float double char 33 @property (nonatomic,assign)int weight; 34 @property (nonatomic,assign,readonly)int idCard; 35 @property (nonatomic,assign,setter = abc:,getter = zhuanghuimei)int height; 36 //改变set与get方法名称很多都是用在BOOL类型的变量 37 @property (nonatomic,assign,setter = isDeid:,getter = isDeid)BOOL isDeid; 38 39 //- (void)isDeid:(BOOL)isDeid; 40 41 //- (void)setHeight:(int)height; 42 //- (int)height; 43 44 /* 45 - (void)setCar:(Car *)car 46 { 47 _car = car; 48 } 49 50 - (Car *)car 51 { 52 return _car; 53 } 54 55 56 - (void)setCar:(Car *)car 57 { 58 59 if (_car != car) 60 { 61 62 [_car release]; 63 //car 2 64 _car = [car retain]; 65 } 66 67 } 68 */ 69 @end
Car.m
1 #import "Car.h" 2 3 @implementation Car 4 5 -(void)dealloc 6 { 7 [super dealloc]; 8 NSLog(@"Car 被销毁了"); 9 } 10 11 @end
Car.h
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 5 @end
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 9 Person * p = [[Person alloc] init]; 10 11 Car * car = [[Car alloc] init]; 12 13 //car 2 14 [p setCar:car]; 15 16 //car 1 17 [car release]; 18 19 20 21 [p abc:100]; 22 int b = [p zhuanghuimei]; 23 p.height = 100;//[p abc:10]; 24 NSLog(@"he %d",p.height);//[p zhuanghuimei]; 25 //p 0 26 27 28 29 [p isDeid:YES]; 30 [p isDeid]; 31 p.isDeid = YES; 32 BOOL result = p.isDeid; 33 34 35 [p release]; 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 } 53 return 0; 54 }
6手动内存管理类相互引用问题
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 - (void)dealloc 5 { 6 [super dealloc]; 7 [_car release]; 8 NSLog(@"Person 被销毁了"); 9 } 10 11 - (void)eat 12 { 13 NSLog(@"人吃东西才有力气"); 14 } 15 16 @end
Person.h
1 #import <Foundation/Foundation.h> 2 #import "Car.h" 3 4 @interface Person : NSObject 5 6 @property(nonatomic,retain) Car * car; 7 8 - (void)eat; 9 10 @end
Car.m
1 #import "Car.h" 2 #import "Person.h" 3 4 @implementation Car 5 6 - (void)dealloc 7 { 8 [super dealloc]; 9 // [_person release]; 10 NSLog(@"Car 被销毁了"); 11 } 12 13 - (void)run 14 { 15 // [_person eat]; 16 [_person eat]; 17 } 18 19 @end
Car.h
1 #import <Foundation/Foundation.h> 2 @class Person; 3 4 @interface Car : NSObject 5 6 //如果你的程序出现相互引用问题,那么一端要改成assign方式,不能够使用retain(回导致内存泄漏问题) 7 @property (nonatomic,assign)Person * person; 8 9 - (void)run; 10 11 @end
main.m
1 // 人拥有一辆车 (组合) 车里面座了一个人 (组合) 2 #import <Foundation/Foundation.h> 3 #import "Person.h" 4 5 int main(int argc, const char * argv[]) 6 { 7 8 @autoreleasepool { 9 10 Person * p = [[Person alloc] init]; 11 12 Car * car = [[Car alloc] init]; 13 14 [p setCar:car]; 15 [car setPerson:p]; 16 17 [car run]; 18 19 [car release]; 20 21 [p release]; 22 23 24 25 } 26 return 0; 27 }
标签:
原文地址:http://www.cnblogs.com/chentaiyan/p/4549568.html