整理之后的
问题
在car自己的dealloc里面设置sefl = nil。
解决过程:
主要的类和分析见下面
main方法
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *fengjie = [Person new];
Car *car1 = [Car new];
car1.speed = 280;
car1.name = @"君越";
[fengjie setCar:car1];//这时候car1 计数器为2
NSLog(@"%lu",[car1 retainCount]);
[car1 release];//这时候car1 计数器为1
NSLog(@"%lu",[car1 retainCount]);
[car1 release];//这时候car1 计数器为0 调用dealloc方法(方法见car.m文件)
NSLog(@"%lu",[car1 retainCount]);//正常结果应该报僵尸错误 但是在 dealloc里面设置sefl = nil 使对象释放失败 这时候返回计数器为 1
//在发下一条消息前 self是指向nil的
Car *susu = [car1 self];
[car1 release];//继续 release 但是这时候对象不会继续自动调用 dealloc 但是计数器返回的数字很奇怪
NSLog(@"%lu",[car1 retainCount]);// 返回 4611686018427387904
NSLog(@"%d",[car1 retainCount]);// 返回 0
//如果重新调用父类的dealloc方法 对象还是可以被释放的 说明释放对象的方法是写在nsobject的dealloc方法里
//[car1 ssss];
//这时候car1 被释放了 继续调用就会报错
//NSLog(@"%@",car1);
[fengjie release];
/*
这个问题最根本的原因有两点
1、self存在作用域 出了dealloc方法后又会重新指向对象(针对这点 后面有详细解释)
2、对象释放 其实是在父类方法里面执行的
结论
以后千万不要在dealloc方法里面写 sefl = nil 这样会造成内存泄漏
引发的其他问题
释放失败之后的计数器 结果是1 当再次 release后 计数器的结果在%lu上是一个很大的数字 在%d中是0
self究竟是什么,详情请见《oc加强2》
*/
}
return 0;
}
Car.m
#import "Car.h"
@implementation Car
- (void)run{
NSLog(@"%@以%d的速度向前奔跑",_name,_speed);
}
- (void) dealloc {
NSLog(@"1----%p",&self);
self = nil; //这样写会造成内存泄漏
NSLog(@"2----%p",&self);
//释放对象内存应该写在父类的方法中 提前把self指向空 父类释放对象就会失败 self 应该也是有作用域的
[super dealloc];
}
-(void)ssss{
NSLog(@"3----%@",self);
[super dealloc];
}
@end
结论
以后千万不要在dealloc方法里面写 sefl = nil 这样会造成内存泄漏 也不要漏写[super dealloc]正真释放内存的方法就在这里
引发的其他问题
释放失败之后的计数器 结果是1 当再次 release后 计数器的结果是一个很大的数字
self究竟是什么,详情请见《oc加强2》 |