最近,修复一个页面返回时有时crash的问题。
业务逻辑是:从商品详情页面可以点击店铺按钮,然后跳转到店铺详情,从店铺详情点击返回按钮,有时候会发生Crash的情况。crash以后main.m文件显示红色的:thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)第一感觉是内存管理出了问题。由于断点调试和查看log都不能解决。于是从常见Crash的解决入手。从而得知是野指针的问题,于是,查看了很多资料。最终这里(http://www.cocoachina.com/bbs/read.php?tid=198249)按照第一个回答者就解决了问题,错误位置是:@property(nonatomic, strong) NLSubViewController *subViewController;每次在viewWillAppear创建View的时候(我感觉很蹩脚,他们写的,不说了):self.subViewController = [[subViewController alloc] init];推出商铺详情的时候,subViewController 被释放(回收掉了),但是这块内存没有写入其他数据,还保存着数据,这就是所说的野指针。跳回来的时候,已经存在内存的subViewController又一次被重新分配内存,还初始化,就会报错。其实也是误打误撞,这个问题压根没有解决楼主的问题。
我的解决方法就是加了一个get方法:
-(NLSubViewController *)subViewController{ if (!_subViewController) { _subViewController = [[subViewController alloc]init]; } return _subViewController;}
其实也可以这么解决,将subViewController 的属性改成weak,这样报警告,说这个对象被释放的时候,weak会将这个对象置为nil。改成assign,则不能运行weak和assign的区别 weak比assign强大,当这个对象被释放的时候,weak会将这个对象置为nil走了很多弯路,
不过也明白了一些问题:
比如怎么xcode怎么打开野指针检测(http://www.bubuko.com/infodetail-807729.html),
怎么查看错误日志(http://www.jianshu.com/p/12a2402b29c2)http://blog.csdn.net/yi_zz32/article/details/48639005 http://blog.csdn.net/xdrt81y/article/details/44960283
附:野指针概念* OC语言: 指针指向的对象已经被回收掉了.这个指针就叫做野指针.* 我们在开发中可能会发现系统并不会时时检测野指针,主要是为了提高编译效率,默认关闭了野指针检测机制crash 日志Exception Type: EXC_CRASH (SIGABRT)Exception Codes: 0x0000000000000000, 0x0000000000000000Exception Note: EXC_CORPSE_NOTIFYTriggered by Thread: 0#import@interface Dog : NSObject
/*
高的总结
基本数据类型 代理对象类型 其他对象类型
手动 MRC: assign weak retain
自动 ARC: assign weak strong(retain)
copy:拷贝(必须遵守NSCopying协议)
@property (nonatomic,strong)NSString *name;
//@property (nonatomic,copy)NSString* name;//浪费内存a,除非是可变字符串
*/
/*
强引用:对这个对象进行强引用,那么对象的引用计数 会 加1;
若引用:对这个对象进行弱引用,那么对象的引用计数 不会 加1;
*/
/*
MRC
copy 对属性进行copy操作
retain 对属性进行强引用
assign 对属性进行弱引用
*/
/*
ARC
可以使用MRC的修饰符(并不是很建议)
strong 类似MRC中的retain,对这个属性进行强引用
weak 类似MRC中的assign,对这个属性进行弱引用
*/
/*
什么时候对象释放
当对象的引用计数为0的时候,对象被释放;000
当没有强引用指针指向对象的时候,对象的引用计数会为0,然后对象会释放
*/
/*
weak和assign的区别
weak比assign强大,当这个对象被释放的时候,weak会将这个对象置为nil
*/
@property (nonatomic,copy)NSString *name;
@property (nonatomic,strong)Dog *dogWife;
@property (nonatomic,assign)NSInteger age;
@property (nonatomic,copy)NSMutableString *strOne;
//dog.strOne=str<==>dog.strOne=[str copy];
//这样写是错的,原因是对一个字符串进行copy之后,得到的是一个不可239变的字符串,而这句话是用可变字符串的指针指向了不可变字符串的对象56
//@property (nonatomic,copy)NSMutableString *strOne;
@property (nonatomic,strong)NSString *strTwo;
/*
工作中的使用:
1、字符串和block使用copy
1)对不可变的字符串使用strong和copy是一样的,建议用copy。
沈说的上面一句,高建议用strong
2)可变字符串不能用copy
2、对代理对象使用weak
3、对简单数据类型(CGFloat,NSInteger,int,long,CGPoint,CGRect)(bool也是)使用assign
4、其他情况用strong
*/
-(void)test;
@end