内存
1.内存管理问题
1⃣️:内存溢出:超出系统分配的内存
2⃣️:野指针异常:[p release];(释放内存)p = nil;(释放指针)
3⃣️:内存泄漏:Person *p2 = [p1 retain];
2.内存管理方式
1⃣️:垃圾回收:
系统来判断哪些空间不再被使⽤用,并回收这些内存空间,以便再次分配
2⃣️:MRC(Manual Reference Count)手动引用计数
内存的开辟和释放都是要由程序员通过代码手动开辟和释
3⃣️:ARC(Auto Reference Count)自动引用计数
允许程序员手动开辟,由编译器通过默认的代码帮助释放,但不是垃圾回收
3.内存管理机制-引用计数
1⃣️:+alloc
①开辟空间
②引用计数从0变1
代码:
Person *per1 = [[Person alloc]init];NSLog(@"%lu",[per1 retainCount]);
2⃣️:-retain
引用计数加1(找个指针指向它,防止出现内存泄漏)
代码:
Person *per3 = [per2 retain]; NSLog(@"%p",per2);NSLog(@"%p",per3);
3⃣️:-copy
4⃣️:-release
引用计数减1
代码:
[per2 release];NSLog(@"%lu",[per2 retainCount]);如果到0就不要在释放了,过度释放会造成崩溃
5⃣️:dealloc
代码:
当引用计数变为0时系统自动调用
- (void)dealloc{// 重写父类的dealloc的方法
[_name release];[_gender release];NSLog(@"被释放了");
[_age release];// assign是标量非对象类型,没有对引用计数产生影响 无需释放
[super dealloc];}
6⃣️:-autorelease和autoreleasepool
-autorelease:在未来的某个时刻引用计数减1
autoreleasepool:自动释放池是一种栈的结构,先进后出
autorelease @autoreleasepool{}
4.内存管理原则:
谁污染谁治理,谁开辟谁释放
注意:
1 retain count 只是为了教课和做题用,但实际上对开发无作用,不要用
2 即使要用的话,不要用它打印系统自带的对象类
3 以后写MRC的工程,无需写(对象 retain)[对象 copy]的方法要注意 alloc之后要release 或者 autorelease然后指针指向nil 在.m写完整dealloc的方法
5.copy
1⃣️main.m
Person *p1 = [[Person alloc]init];
Person *p2 = [p1 copy];// [p1 retain]浅拷贝
NSLog(@"%p",p1);
NSLog(@"%p",p2);
[p1 release];
[p2 release];
p1 = nil;
p2 = nil;
2⃣️浅拷贝
- (instancetype)copyWithZone:(NSZone *)zone{
// self retain 把引用计数加1
return [self retain];//浅拷贝:相当于只拷贝了指针
//(retain 只不过它遵循了nscopying协议)
// 指向新的内存}
3⃣️深拷贝
- (instancetype)copyWithZone:(NSZone *)zone{
Person *p = [[Person alloc]init];
p.name=self.name;
return p;}
// 深拷贝:新建了一个对象,将对象return出去
// 真正意义上的拷贝,他是开辟了一个新的空间 对象也return过去
注意:
NSLog(@"%lu",NSUIntegerMax);// 18446744073709551615