读《招聘一个靠谱的 iOS》-- 代码风格
2015-08-04 11:36
666 查看
题目:
尝试修改以下代码中的风格错误:
———————————————————我是分割线——————————————————–
博主在平时code时一直很注重自己的代码风格,固在修改此题可以说是信心十足,但修改下来也就发现9处错误,还只是一些浅显的“硬伤”,没有什么技术含量,而结合网上的一些错误修改却发现十多条的“可优化部分”!
真是平时没有严格要求住自己,才会让自己把一些错误的事情当做正确的事情来执行!
———————————————————我是分割线——————————————————–
先附上网上的一种优秀的修改方法 (稍加修改版):
下面对具体修改的地方,分两部分做下介绍:硬伤部分和优化部分
。因为硬伤部分没什么技术含量,为了节省大家时间,放在后面讲,大神请直接看优化部分。
可优化部分(代码由上往下看):
1、enum
enum官方给出的推荐方法中已经摒弃简单的
举例:
2、一般类名需要在加上前缀,用以分割项目中的所属模块或者与第三方类区分
3、熟悉定义的时候优于
得出修改结果:
注:后面的文章会说到为什么要把strong改成copy,大概可以理解为
4、
从命名所表达的意思来看,属性age应该代表的是岁数,而岁数为非负整数,所以使用NSUInteger优于int。
这样做的是基于64-bit 适配考虑,详情可参考出题者的博文《64-bit Tips》
5、方法命名不规范
观察方法名,不难理解到此方法适用于用参数来初始化一个实力
1) 返回类型
2) 名称用
3) 参数需要遵循原则:
4) 初始化时漏掉参数
最后得出结果:
doLogIn方法命名不规范:添加了多余的动词前缀。 请牢记:
6、MVC而非MVVM
由于博主代码风格一值都是使用MVVM,所以对此不做过多评价,所以贴出大神原话:
注:即使是在MVVM中,login这种方法也不应该出现再次出,此类偏向于数据模型,并不属于业务逻辑范畴。
尝试修改以下代码中的风格错误:
———————————————————我是分割线——————————————————–
博主在平时code时一直很注重自己的代码风格,固在修改此题可以说是信心十足,但修改下来也就发现9处错误,还只是一些浅显的“硬伤”,没有什么技术含量,而结合网上的一些错误修改却发现十多条的“可优化部分”!
真是平时没有严格要求住自己,才会让自己把一些错误的事情当做正确的事情来执行!
———————————————————我是分割线——————————————————–
先附上网上的一种优秀的修改方法 (稍加修改版):
typedef NS_ENUM(NSInteger, DBSex) { DBSexMan, DBSexWoman }; @interface DBUser : NSObject<NSCopying> @property (nonatomic, copy , readonly) NSString *name; @property (nonatomic, assign, readonly) NSUInteger age; @property (nonatomic, assign, readonly) DBSex sex; - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(DBSex)sex; - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age; @end
下面对具体修改的地方,分两部分做下介绍:硬伤部分和优化部分
。因为硬伤部分没什么技术含量,为了节省大家时间,放在后面讲,大神请直接看优化部分。
可优化部分(代码由上往下看):
1、enum
enum官方给出的推荐方法中已经摒弃简单的
typedef enum这种写法了,而是用
NS_ENUM和
NS_OPTIONS宏来定义枚举类型,参见官方的 Adopting Modern Objective-C 一文:
举例:
//定义一个枚举 typedef NS_ENUM(NSInteger, DBSex) { DBSexMan, DBSexWoman };
2、一般类名需要在加上前缀,用以分割项目中的所属模块或者与第三方类区分
3、熟悉定义的时候优于
原子属性(nonatomic)在绝大多数情况下是需要的,所以统一写在第一位,观察下面有该类的初始化方法,固猜测此此类中属性是不允许随意被外界修改的(需要修改需要有特定的方法),所以在属性中需要加上
readonly属性。
得出修改结果:
@property (nonatomic, copy , readonly) NSString *name; @property (nonatomic, assign, readonly) NSUInteger age; @property (nonatomic, assign, readonly) DBSex sex;
注:后面的文章会说到为什么要把strong改成copy,大概可以理解为
指针本身的地址和
指针指向的地址的区别,说白了就是浅复制和深复制的区别。
4、
NSInteger、
NSUInteger、
NSTimeInterval、
CGFloat、
int、
float、
unsigned
int -> NSInteger unsigned -> NSUInteger float -> CGFloat 动画时间 -> NSTimeInterval
从命名所表达的意思来看,属性age应该代表的是岁数,而岁数为非负整数,所以使用NSUInteger优于int。
这样做的是基于64-bit 适配考虑,详情可参考出题者的博文《64-bit Tips》
5、方法命名不规范
-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;
观察方法名,不难理解到此方法适用于用参数来初始化一个实力
DBUser方法,所以:
1) 返回类型
id改为
instancetype会更加明了;
2) 名称用
init足以表达意思
initUserModel会略显臃肿;
3) 参数需要遵循原则:
**with连接第一个独立个参数,相对独立参数用and连接,并列参数不要任何任何动词连接。**(此处仅代表博主个人意见,如有不同,请指出!)
//错误,不要使用"and"来连接参数 - (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; //错误,不要使用"and"来阐明有多个参数 - (instancetype)initWithName:(CGFloat)width andAge:(CGFloat)height; //正确,使用"and"来表示两个相对独立的操作 - (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
4) 初始化时漏掉参数
sex,在不太改动原来方法的情况下,应该拆分为两个独立的方法。
最后得出结果:
- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(DBSex)sex; - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age;
doLogIn方法命名不规范:添加了多余的动词前缀。 请牢记:
如果方法表示让对象执行一个动作,使用动词打头来命名,注意不要使用do,does这种多余的关键字,动词本身的暗示就足够了。
6、MVC而非MVVM
由于博主代码风格一值都是使用MVVM,所以对此不做过多评价,所以贴出大神原话:
doLogIn方法不应写在该类中:虽然LogIn的命名不太清晰,但笔者猜测是login的意思,而登录操作属于业务逻辑,观察类名UserModel,以及属性的命名方式,应该使用的是MVC模式,并非MVVM,在MVC中业务逻辑不应当写在Model中。(如果是MVVM,抛开命名规范,UserModel这个类可能对应的是用户注册页面,如果有特殊的业务需求,比如:login对应的应当是注册并登录的一个Button,出现login方法也可能是合理的。)
注:即使是在MVVM中,login这种方法也不应该出现再次出,此类偏向于数据模型,并不属于业务逻辑范畴。
硬伤部分 1.在-和(void)之间应该有一个空格 2.enum中驼峰命名法和下划线命名法混用错误:枚举类型的命名规则和函数的命名规则相同:命名时使用驼峰命名法,勿使用下划线命名法。 3.enum左括号前加一个空格,或者将左括号换到下一行 4.enum右括号后加一个空格 5.UserModel :NSObject 应为UserModel : NSObject,也就是:右侧少了一个空格。 6.@interface与@property属性声明中间应当间隔一行。 7.两个方法定义之间不需要换行,有时为了区分方法的功能也可间隔一行,但示例代码中间隔了两行。 8.-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中方法名与参数之间多了空格。而且- 与(id)之间少了空格。 9.-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中方法名与参数之间多了空格:(NSString*)name前多了空格。 10.-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中(NSString*)name,应为(NSString *)name,少了空格。 11.doLogIn方法命名不清晰:笔者猜测是login的意思,应该是粗心手误造成的。 12.第二个@property中assign和nonatomic调换位置。
相关文章推荐
- IOS自动布局二
- iOS 图片与内存(转)
- iOS 常用颜色值转换类
- iOS开发之保存照片到系统相册(Photo Album)
- iOS行货自动打包
- iOS 计算字符串的高度类
- ios手柄研究
- ava垃圾加收机制和ios的arc有什么区别
- iOS button 同时设定图片和文字
- iOS 高效 Mac 配置
- iOS开发 获取应用名称和版本号
- IOS自动布局一
- 通过iOS中的按钮来触发html文件中按钮所触发的函数
- iOS开发 将图片打包编码以便上传
- iOS-登陆界面 实现光标换行功能
- iOS开发 字符串转换成字典
- iOS UTF-8、URL解码与转码
- iOS8新功能 tableviewcell 自适应高度 iPhone5siPhone6 与iPhone6p的差异设置
- 苹果开发 笔记(56)下载zip文件到沙箱更新
- iOS 9 更新之Safari广告拦截器(Content Blocker)开发教程