2023年7月13日发(作者:)
让代码更帅⼀点写代码最重要的是实现功能,但是除了实现功能之外,我们还应该想办法,让代码变得更规范,更漂亮
最近在读和,这两本都讲解了代码规范⽅⾯的东西,结合⾃⼰平时的代码习惯,发现有很多地⽅⾃⼰做的还是不够好,代码写得不够帅,所以总结⼀下,让以后的代码更帅⼀点条件语句条件语句⼀定要使⽤括号,如果不使⽤括号,if后⾯的那⾏代码删除,之后的代码会成为if语句⾥⾯的代码
推荐:if (!error) { return success;}括号⼤括号的使⽤最好跟Apple保持⼀致,⼤括号在同⼀⾏开始,在新的⼀⾏结束,
如:if (y) { //Do something}else { //Do something else}nil和BOOL判断最好直接使⽤!判断nil,或者BOOL值
推荐:if (![someObject boolValue]) { ...if (!someObject) { ...避免嵌套if不要嵌套 if 语句。使⽤多个 return 可以避免增加循环的复杂度,并提⾼代码的可读性。
推荐:- (void)someMethod { if (![someOther boolValue]) { return; } //Do something important}不推荐:- (void)someMethod { if ([someOther boolValue]) { //Do something important }}多⽤字⾯量语法何为字⾯量语法NSString *string = @"string";NSNumber *intNumber = @88;NSNumber *boolNumber = @YES;NSNumber *floatNumber = @3.14;int var = 3;NSNumber *varNumber = @(var);NSArray *list = @[@"itme1",@"item2",@"item3"];NSLog(@"%@,%@,%@",list[0],list[1],list[2]);NSDictionary *map = @{@"key1":@"value1",@"key2":@"value2"};NSLog(@"%@,%@",map[@"key1"],map[@"key2"]);这就是字⾯量语法,⽤⾮常简单直观的⽅法创建或者获取常⽤的对象(NSString,NSNumber,NSArray,NSDictionary),使⽤字⾯量语法简单⽅便直观复杂的表达式当有⼀个复杂的if语句时,可以把判断条件提取出来作为BOOL变量BOOL nameContainsSwift = [sessionName containsString:@"Swift"];BOOL isCurrentYear = [sessionDateCompontents year] == 2014;BOOL isSwiftSession = nameContainsSwift && isCurrentYear;if (isSwiftSession) { // Do something very cool}⽤常量代替宏推荐:static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";static const NSTimeInterval animationDuration = 3.0;不推荐:#define ZOCCacheControllerDidClearCacheNotification @"ZOCCacheControllerDidClearCacheNotification"#define animationDuration 3.0原因:
1. 使⽤宏的过程中⽆法直接知道常量类型(是int呢?还是Stiring呢?),除⾮查看宏定义的地⽅
2. 宏可以更改,,如果2个地⽅使⽤同样的名字定义了2个不⼀样的宏,你使⽤的时候可能会使⽤错误,造成难以发现的bug。使⽤const定义的常量如果更改编译器就会报错static在常量的使⽤过程中分两种情况
1.常量需要对外暴露。不使⽤static,并在.h中⽤extern暴露出去// .hextern NSString *const ZOCCacheControllerDidClearCacheNotification;// .mNSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";2.常量只在本类中使⽤,不需要对外暴露,使⽤ NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";static定义的变量仅在当前的.m⽂件中可见,如果常量只在本类中使⽤,⽤static会避免影响到其他类,如果需要全局可见,就不能使⽤static类命名冲突1)类名,全局变量和C函数(C函数类似于全局变量)命名时,使⽤三个字母作为前缀,避免命名跟第三⽅API或者苹果API名称冲突
项⽬⾥经常看到不使⽤前缀或者使⽤两个字母作为前缀的命名⽅式。
不使⽤前缀可能发⽣冲突不⾔⽽喻,那为什么不使⽤两个字母作为前缀呢?
因为Apple宣称其保留使⽤所有”两字母前缀”的权利,使⽤两字母作为前缀有跟未来的苹果API冲突的风险,所以保险起见,尽量使⽤三个字母作为iOS的命名前缀2)类内部使⽤的私有⽅法,可以加个前缀,但不要使⽤单个下划线_作为前缀,因为这也是Apple预留的。可以使⽤双下划线__或者p_作为前缀3)如果需要为⽆源码的类(包括第三⽅类和系统类)添加category,⽅法名称前最好带前缀,避免冲突Designated Initializer⼦类重新定义designated initializer时应遵循以下步骤:1. 定义designated initializer,并调⽤⽗类的designated initializer2. 重载⽗类的designated initializer,并调⽤新定义的designated initializer3. 为新的designated initializer写⽂档在.h中,使⽤__attribute__((objc_designated_initializer))标明哪个是designated initializer。
如果因为某些原因,⽗类的designated initializer被弃⽤,⽐如designated initializer必须要有某个参数,⽗类的designated initializer⽆法传这个参数。⽤__attribute__((unavailable("Invoke the designated initializer")))表⽰弃⽤- (instancetype)initWithName:(NSString *)name __attribute__((objc_designated_initializer));- (instancetype)init __attribute__((unavailable("Invoke -initWithName:")));类的封装在封装⼀个类的时候,下⾯⼏点需要注意:1. 外部不需要了解的属性和⽅法,尽量定义在.m中2. 不要轻易暴露属性的setter⽅法,多使⽤readonly3. 尽量使⽤不可变对象4. 不要暴露可变的collection,应该提供相应的⽅法替代protocol1)⼀般情况下protocol分为2类,delegate和dataSource1. delegate:委托别的类去⼲活的,需要放在delegate⾥⾯,⼀般没有返回值2. dataSource:去别的类获取数据的,放在dataSource⾥⾯,主要⽤于获取数据2)delegate属性在ARC下,⼀定要⽤weak取代assign,避免隐患
3)对于option的protocol。在调⽤之前⼀定要⽤-respondsToSelector:判断这个⽅法是否实现了属性规范从代码规范和漂亮的⾓度来说,属性最好这样写,这是apple的写法
推荐:@property(nonatomic, readonly, copy) NSString *nibName;
不推荐:@property(nonatomic, readonly, copy) NSString* nibName;
@property(nonatomic, readonly, copy)NSString *nibName;
@property (nonatomic, readonly, copy) NSString *nibName;
...setter&getter属性除了init和dealloc外,建议使⽤setter和getter⽅法。在init和dealloc中,建议直接使⽤ivar
使⽤setter和getter⽅法的好处:1. 遵守内存管理语义(strong,copy…)2. kvo通知会⾃动被执⾏3. ⽅便debug,打断点4. ⽅便重写getter或者setter为什么不要在init和dealloc中使⽤setter和getter?
如果init中使⽤了setter,在⼦类的属性初始化之前,调⽤[super init]的时候就会调⽤setter⽅法。这时候如果重写了setter,并在setter中做了特殊的操作,这时候就可能会引起⼀些⾮常难发现的bug。所以为了避免隐患,在init或者dealloc中直接使⽤ivar可变对象赋值对可以⽤可变对象赋值的属性(如:NSString,NSArray,NSDictionary),属性的内存管理类型必须为copy。这是为了防⽌可变对象(NSMultableArray)给不可变对象(NSArray)赋值。导致不可变对象(NSArray)指针指向可变对象(NSMultableArray),在使⽤过程中可能会改变它的值,出现bug点符号当使⽤属性的时候尽量使⽤.符号,⽅法调⽤使⽤[]
例: oundColor = [UIColor orangeColor];[UIApplication sharedApplication].delegate;Block推荐这种block使⽤⽅法__weak __typeof(self)weakSelf = self;[self executeBlock:^(NSData *data, NSError *error) { __strong __typeof(weakSelf) strongSelf = weakSelf; if (strongSelf) { [strongSelf doSomethingWithData:data]; [strongSelf doSomethingWithData:data]; }}];在block外⾯⽤weak持有self,避免循环引⽤
在block⾥⾯⽤strong持有self,避免多线程中block执⾏到⼀半,self被释放为nil,⽽出现的隐患
其他的block问题,可以看以前写的可变集合永远不要枚举可变集合推荐:NSArray *staticArray = [multableArray copy];for (id item in staticArray) { ....}不推荐:for (id item in multableArray) { ....}可变集合在枚举时如果发⽣改变,会引起crash。
永远不要枚举可变集合,不管你有多么确定这个集合不会改变。因为代码也许以后会被修改,也许有别的线程会改变这个集合,太多意外可能会发⽣,唯⼀能保证不会有意外的就是永远不要枚举可变集合不要将可变集合暴露成公共属性推荐:// .h@property(nonatomic, readonly) NSArray *staticArray;// .m@property(nonatomic, strong) NSMutableArray *mutableArray;- (NSArray *)staticArray{ return [eArray copy];}不推荐①:// .h@property(nonatomic, readonly)NSMutableArray *mutableArray;不推荐②:// .h@property(nonatomic, readonly) NSArray *staticArray;// .m@property(nonatomic, strong) NSMutableArray *mutableArray;- (NSArray *)staticArray{ return eArray;}你永远不知道外⾯会怎么⽤这个mutableArray,假设外⾯正在枚举这个mutableArray,在其他线程mutableArray被改变了。嘭,Crash了,还不是毕现,⼜是加班的节奏了…如果在外部需要改变这个Array⾥⾯的item,添加改变item的⽅法:// .h@property(nonatomic, readonly) NSArray *staticArray;- (void)addItem:(id)item;- (void)removeItem:(id)item;//.m@property(nonatomic, strong) NSMutableArray *mutableArray;- (void)addItem:(id)item{ [eArray addObject:item];}- (void)removeItem:(id)item{ [eArray removeObject:item];}NSNotificationremovenotification⼀定要remove!
notification⼀定要remove!!
notification⼀定要remove
重要的东西⼀定要说三遍,Notification不remove很容易crash,包括KVO,也⼀定要记得remove,否则会有crash在前⽅等着你…多次注册notification如果多次注册会导致⼀次post,⽅法多次被调⽤,所以注意注册通知的时候⼀定要看清楚,是否通知只注册了⼀次,建议在init中注册通知,dealloc中remove通知Reference
发布者:admin,转转请注明出处:http://www.yc00.com/news/1689262884a226342.html
评论列表(0条)