代码不规范容易造成的bug
1.子类初始化方法调用父类的副初始化方法---死循环
//代码说明:Father继承自NSObject,Children继承自Father,在执行了控制器MyVC中的代码后,会发生什么?@implementation Father
- (instancetype)initWithUrl:(NSString *)url title:(NSString *)title{
if (self = [super init]) {
NSLog(@"父111111111");
}
NSLog(@"父2222222222");
return self;
}
- (instancetype)initWithUrl:(NSString *)url{
NSLog(@"父333333333333");
return [self initWithUrl:url title:nil];
}@implementation Children
- (instancetype)initWithUrl:(NSString *)url title:(NSString *)title{
if (self = [super initWithUrl:url]) {
NSLog(@"子44444444444");
}
NSLog(@"子5555555555");
return self;
}@implementation MyVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
Children *child = [[Children alloc]initWithUrl:@"http://www.baidu.com" title:@"标题"];
}// 代码会按照:Children:[super initWithUrl:url] ---> Father: initWithUrl这个顺序循环执行,不停打印“父333333333333”;
【代码不规范容易造成的bug】2.在dealloc方法中,将self作为参数传递出去----Crash
-(void)dealloc{
[self unsafeMethod:self];
// 因为当前已经在self这个指针所指向的对象的销毁阶段,销毁self所指向的对象已经在所难免。如果在unsafeMethod:中把self放到了autorelease poll中,那么self会被retain住,计划下个runloop周期在进行销毁。但是dealloc运行结束后,self所指向的对象的内存空间就直接被回收了,但是self这个指针还没有销毁(即没有被置为nil),导致self变成了一个名副其实的野指针。
// 到了下一个runloop周期,因为self所指向的对象已经被销毁,会因为非法访问而造成crash问题。
}
3.ios8及更早的版本中 通知的处理 可能导致Crash
//NSNotificationCenter在iOS8及更老的系统有一个多线程bug,selector执行到一半可能会因为self的销毁而引起crash,解决的方案是在selector中使用weak_strong_dance。
- (void)onMultiThreadNotificationTrigged:(NSNotification *)notify {
__weak typeof(self) wself = self;
__strong typeof(self) sself = wself;
if (!sself) { return;
}
[self doSomething];
}
4.官方推荐的一些规范
1.如果想要获取window,不要使用view.window获取。请使用[[UIApplication sharedApplication] keyWindow]。2.在使用到 UIScrollView,UITableView,UICollectionView 的 Class 中,需要在 dealloc 方法里手动的把对应的 delegate, dataSouce 置为 nil。3.UITableView使用self-sizing实现不等高cell时,请在 cellForRowAtIndexPath: 中给cell设置数据。不要在 willDisplayCell:forRowAtIndexPath: 方法中给cell设置数据。4.当访问一个 CGRect 的 x, y, width, height 时,应该使用CGGeometry 函数代替直接访问结构体成员。
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
反对这样的写法:
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
推荐阅读
- 急于表达——往往欲速则不达
- CVE-2020-16898|CVE-2020-16898 TCP/IP远程代码执行漏洞
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 家乡的那条小河
- 一个人的碎碎念
- 赠己诗
- 这辈子我们都不要再联系了
- 死结。
- 我从来不做坏事
- 时间老了