企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 我的 iOS 代码规范 [TOC] *** 参考资料: - VV木公子:一份走心的iOS开发规范 https://www.jianshu.com/p/c818c00e0690 # 类型 使用到整形变量时,建议使用NSInteger NSUInteger,不建议使用int,uint 。 使用float时,建议使用CGFloat # 常量 建议 ``` static NSString *const PLMessageCountChanageNotificationName = @"MessageCountChanageNotification" static NSUInteger const PLRetryMaxCount = 5 ``` 不建议 ``` #define PLMessageCountChanageNotificationName @"MessageCountChanageNotification" #define PLRetryMaxCount 5 ``` # 变量 遵循驼峰模式即可 对于实例变量建议以下划线开始命名 ``` @interface Foo() { NSString *_name } @end ``` 对于局部变量建议不要以下划线开头, 避免误解变量的作用域 不建议 ``` - (void)uploadVideo { NSString *_name = @""; } @end ``` # 字面值 对于NSString, NSDictionary, NSArray, 以及 NSNumber 支持语法糖 建议 ``` NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"}; NSNumber *shouldUseLiterals = @YES; NSNumber *buildingStreetNumber = @10018; ``` 不建议 ``` NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil]; NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil]; NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES]; NSNumber *buildingStreetNumber = [NSNumber numberWithInteger:10018]; ``` # 枚举 当使用 `enum` 的时候,建议使用新的固定的基础类型定义,因为它有更强大的类型检查和代码补全。 SDK 现在有一个 宏来鼓励和促进使用固定类型定义 `- NS_ENUM()` 建议 ``` typedef NS_ENUM(NSInteger, UIViewAnimationCurve) { UIViewAnimationCurveEaseInOut, // slow at beginning and end UIViewAnimationCurveEaseIn, // slow at beginning UIViewAnimationCurveEaseOut, // slow at end UIViewAnimationCurveLinear, }; ``` ``` typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 }; ``` 不建议 ``` enum UIViewAnimationCurve { UIViewAnimationCurveEaseInOut, // slow at beginning and end UIViewAnimationCurveEaseIn, // slow at beginning UIViewAnimationCurveEaseOut, // slow at end UIViewAnimationCurveLinear, }; ``` # 控制语句 ## 关于if ### 一行代码: 条件语句体应该总是被大括号包围。尽管有时候你可以不使用大括号(比如,条件语句体只有一行内容),但是这样做会带来问题隐患。比如,增加一行代码时,你可能会误以为它是 if 语句体里面的。此外,更危险的是,如果把 if 后面的那行代码注释掉,之后的一行代码会成为 if 语句里的代码。 建议 ``` if (!error) { return success; } ``` 不建议 ``` if (!error) return success; or if (!error) return success; ``` 多行代码: 在if中对于花括号`{`的处理应该趋于书写在行尾,这样控制条件和控制语句容易被视为一个整体。 建议 ``` if(condition) { //... } else { //... } ``` 不建议 ``` if(condition) { //.. } else { //.. } ``` ### 尤达表达式 不要使用尤达表达式。尤达表达式是指,拿一个常量去和变量比较而不是拿变量去和常量比较。它就像是在表达 “蓝色是不是天空的颜色” 或者 “高个是不是这个男人的属性” 而不是 “天空是不是蓝的” 或者 “这个男人是不是高个子的” ![yoda](media/14988919579371/yoda.png) 推荐 ``` if ([myValue isEqual:@42]) { ... ``` 不推荐 ``` if ([@42 isEqual:myValue]) { ... ``` ### 多层嵌套 在使用条件语句编程时,不要嵌套 if 语句。使用多个 return 可以避免增加循环的复杂度,并提高代码的可读性。因为方法的重要部分没有嵌套在分支里面,并且你可以很清楚地找到相关的代码。 推荐 ``` - (void)someMethod { if (![someOther boolValue]) { return; } //Do something important } ``` 不推荐 ``` - (void)someMethod { if ([someOther boolValue]) { //Do something important } } ``` ### 复杂的表达式 当你有一个复杂的 if 子句的时候,你应该把它们提取出来赋给一个 BOOL 变量,这样可以让逻辑更清楚,而且让每个子句的意义体现出来。 推荐 ``` BOOL nameContainsSwift = [sessionName containsString:@"Swift"]; BOOL isCurrentYear = [sessionDateCompontents year] == 2014; BOOL isSwiftSession = nameContainsSwift && isCurrentYear; if (isSwiftSession) { // Do something very cool } ``` ## 关于switch 括号不是必须的,为了代码结构层次清晰,建议加上括号。 ``` switch(condition){ case 1: { //one line or multi-line } break; default: break; } ``` 对于枚举类型的switch,可以不需要default ``` UIViewAnimationCurve curveType = UIViewAnimationCurveEaseInOut; switch(curveType) { case UIViewAnimationCurveEaseInOut: { } break; case UIViewAnimationCurveEaseIn: { } break; case UIViewAnimationCurveEaseOut: { } break; case UIViewAnimationCurveLinear: { } break; } ``` ## 关于for循环 对于集合类型(array,set) 建议使用 enumerateObjectsUsingBlock ``` NSArray *nameArray = @[@"Kita","jonas"]; [nameArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { //... }]; ``` 其次可以选择for in 如果不需要索引的话 ``` for(NSString *name in nameArray) { //... } ``` ## 三目运算符 三目运算符 `?` 应该只用在它能让代码更加清楚的地方。 一个条件语句的所有的变量应该是已经被求值了的。类似 if 语句,计算多个条件子句通常会让语句更加难以理解。或者可以把它们重构到实例变量里面。 推荐 ``` result = a > b ? x : y; ``` 不推荐 ``` result = a > b ? x = c > d ? c : d : y; ``` # 属性 对于属性修饰符要全都指示出来,对于纯量类型默认是(atomic,assign),对于对象类型默认是(atomic,strong)。权限修饰符默认readwrite可以不写,一般情况下属性都是readwrite,对于只读属性需要写明readonly 对于有可变类型的类(NSString,NSArray,NSDictionary,NSSet) 建议使用copy,是因为有可能引用可变对象 建议 ``` @property (nonatomic, copy) NSString *name; @property (nonatomic, strong) UIView *containerView; ``` 不建议 ``` @property(nonatomic,strong) NSString *name; @property(nonatomic) UIView *containerView; ``` # 方法 方法类型(-/+)后需要空一格 建议 ``` - (void)setTitle:(nullable NSString *)title forState:(UIControlState)state; ``` 不建议 ``` -(void)setTitle:(nullable NSString *)title forState:(UIControlState)state; ``` # 注释 文件注释 注释是代码可读性的关键,最好的代码应该自成文档。 其他注释(类注释,方法注释等) xcode8 建议使用自带注释快捷键 command+option+/ # 代码结构组织 viewController类的建议 ``` @property (nonatomic, strong) UITableView *tableView; ... #pragma mark - Life cycle (生命周期) - (instancetype)init {} - (void)viewDidLoad {} - (void)viewWillAppear:(BOOL)animated {} - (void)didReceiveMemoryWarning {} - (void)dealloc {} #pragma mark - UITableViewDelegate (代理协议) - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {} ... #pragma mark - LMFootViewButtonDelegate(代理协议) -(void)footViewDidSelectedButton:(UIButton *)sender andIndex:(NSInteger)index andButtonTitle:(NSString *)titleText{} ... #pragma mark - IBActions(event response) - (IBAction)submitData:(id)sender {} ... #pragma mark - Private Methods - (void)privateMethod {} ... #pragma mark - Getter and Setter - (NSString *)name; - (void)setName:(NSString *)name; ``` # 使用CGRect函数 建议 ``` CGRect frame = self.view.frame; CGFloat x = CGRectGetMinX(frame); CGFloat y = CGRectGetMinY(frame); CGFloat width = CGRectGetWidth(frame); CGFloat height = CGRectGetHeight(frame); CGRect frame = CGRectMake(0.0, 0.0, width, height); ``` 不建议 ``` CGRect frame = self.view.frame; CGFloat x = frame.origin.x; CGFloat y = frame.origin.y; CGFloat width = frame.size.width; CGFloat height = frame.size.height; CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size }; ``` # Tips ## 行宽 尽量保持在100以内,具体设置如下: >Xcode->Preferences->Text Editing->Page guide at column