iOS代码规范

-------------------------------------编码原则-------------------------------------

  • 需求是暂时的,只有变化才是永恒的,面向变化编程,而不是面向需求编程;
  • 不要过分追求技巧,从而降低程序的可读性
  • 简洁的代码可以让bug无处藏身,要写出明显没有bug的代码,而不是没有明显bug的代码
  • 先解决问题,再考虑将来的扩展问题。
    -------------------------------------编码原则-------------------------------------

代码格式化

  • 使用系统自带的格式化工具,选中要格式化的代码后使用control + i快捷键进行代码格式化

代码片段

  • CodeSnippets文件夹放到这里/Users/xxxx/Library/Developer/Xcode/UserData下面,重启Xcode即可
  • 代码片段使用说明
代码片段快捷键 片段说明
sk_mark 快速添加mark注释
sk_mark_controller_methods 控制器中方法布局
sk_mark_single_lifeCycle 控制器view生命周期方法汇总
sk_mark_single_intial 页面初始化相关方法汇总
sk_mark_single_network 网络请求相关方法
sk_mark_single_override 重载的方法
sk_mark_single_eventResponse 事件和响应方法汇总
#pragma mark - <UITableViewDelegate> 代理方法汇总
sk_mark_single_public 对外公开的方法汇总
sk_mark_single_private 私有方法汇总
sk_mark_single_gettersAndSetters 属性集中营
sk_view_Define 自定义view
sk_pro_assign 快速定义assign属性
sk_pro_copy 快速定义copy属性
sk_pro_strong 快速定义strong属性
sk_pro_weak 快速定义weak属性
sk_block_var 定义block变量,直接定义属性或成员变量
sk_block_typedef 定义block类型
sk_yy_pro_whiteList 属性白名单,当不参与转换的属性个数远远超过参与转换的属性个数时可以用此方法来指定哪些属性需要参与字典转模型
sk_yy_property_blackList 在黑名单中属性“不参与”字典转模型
sk_yy_propertyMapper 属性映射
sk_yy_array_objectMapper 指定数组属性中的实体类型
sk_request_multiple 多个请求优雅处理
sk_single_obj 实现单例对象

开发中遇到的规范问题总结

  • 引用的头文件需要做归类处理,见下面关于在Controller和View中头文件的分类规范
  • 正确使用空格,不要有多余的空格
    • 属性定义要有合适的空格
    @property (nonatomic, copy, readonly) NSString *userName;
    
    • 方法定义要有合适的空格
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    }
    
    • 属性与属性间不要有空格
    @property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
    @property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
    
    • 方法与方法之间必须有一个空格的间隙
    - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
    
    - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
    
  • 做好属性归类,eg: 视图属性放在一起,数据属性放在一起等
  • 头文件引入规范
  • 代理引入书写规范,超过三个以上的代理就要按如下格式
@interface HCConversationListViewController ()
<
UITableViewDelegate,
UITableViewDataSource,
MGSwipeTableCellDelegate,
HCIMConversationListManagerDelegate
>
  • 警告必须去除
  • 注释规范,不要自己敲,直接使用快捷键command+option+/生成
  • 私有方法命名规范,私有方法统一使用下划线开头
  • 使用代码片段来统一规范
  • 少用宏,多用常量
  • if层级嵌套不允许超过三级要善于使用return来提前返回错误的情况,把最正确的情况放到最后返回
  • 不能超过1000行方法不能超过100行
  • 使用局部变量接收一个链式调用的属性值,再用这个局部变量再去完成后面的逻辑
// 先用一个临时变量接收常常的属性值
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
// 再在下面使用keyWindow,不要使用[UIApplication sharedApplication].keyWindow
  • 多处使用的字符串需要定义成常量,不允许直接使用字符串
  • 字典不允许采取@{}的方式定义,使用NSMutableDictionary的方式定义
  • 不要在Controller里进行数据加工,放到Manager里
  • 不要直接使用int,而应该使用NSInteger
  • 在头文件里说明类的用途


    类的用途
  • 删除无用的注释代码
  • 同样的功能不能写多份
  • 不要在init和dealloc函数中使用属性
  • subView的初始化放到getter中去做,getter和setter全部都放在类的最后
  • 少用storyboard、xib
  • 万不得已不要用继承,优先考虑组合

团队Xcode 开发统一开发字体

  • 这里推荐JetBrains Mono,据说 JetBrains Mono 是最适合程序员的字体之一
  • JetBrains Mono字体下载
  • Mac直接选择系统自带的字体册程序设置字体,设置如下
    添加字体
  • 另外一种安装方法:将下载的字体压缩文件的zip后缀改成otf,然后双击安装即可

名词定义

  • 大驼峰式命名:每个单词的首字母都采用大写字母
  • 小驼峰式命名:第一个单词首字母小写,剩下单词的首字母大写

命名规范

  • 命名原则
    • 明确表达含义,尽量做到不需要注释也能了解其作用,若做不到,就加注释
    • 使用全称,尽量不使用缩写(使用规范的缩写,不要自创);
    • 公共接口不仅命名要规范,也要添加上注释,方便使用者快速了解接口的含义,最好在注释里给出使用示范

类名

  • 采取大驼峰式命名
  • 示例:XXHomeViewController,XX是项目前缀,不属于命名范畴,这里不要产生误解

私有变量

  • 私有成员变量在.m文件中声明
  • 以_开头,小驼峰式命名,示例:NSString *_privateVar;或者在扩展类中定义属性,二者选其一即可

property变量

  • 小驼峰式命名,示例:userName
  • @property和左括号间有空格,有括号和类型间有空格,括号累不修饰符之间有空格,星号和变量名之间没有空格,属性的修饰关键字推荐排序:原子性,内存管理,读写权限(默认是可读写),示例:
  • iOS中不建议使用atomic修饰符
@property (nonatomic, copy, readonly) NSString *userName;
  • NSString、NSArray、NSDictionary、block属性应该使用copy关键字;

宏常量命名

  • #define预处理定义的宏常量全部大写,单词间用_分隔,示例:
#define MD_SCREEN_BOUNDS   [[UIScreen mainScreen] bounds]
  • 宏定义中如果包含表达式或变量,表达式或变量必须用小括号括起来,示例:
#define MD_SCALING   ([[UIScreen mainScreen] bounds].size.width/375.f) // 缩放比例

类型常量命名

  • 对于仅在.m文件中使用的常量要使用static进行定义,命名方面以字符k开头,示例:static NSTimeInterval const kAnimationDuration = 0.3;
  • 对于定义于.h文件中的常量,对外部可见,则以定义该常量所在类的类名开头(仿照苹果风格),在头文件中使用UIKIT_EXTERN声明,在.m文件中定义其值,示例:
//在.h文件中:
UIKIT_EXTERN NSString * const UIApplicationStatusBarOrientationUserInfoKey;

//在.m文件中:
NSString * const UIApplicationStatusBarOrientationUserInfoKey = @"xxxxxx";

block

  • 使用dispatch_block_t替代void (^XXXBlock)()这类型的block

枚举

  • 与类的命名规则一致,采取大驼峰式命名,示例:UIControlState
  • 枚举内容的命名需要以该枚举的类型名称开头,示例:UIControlStateNormal
  • NS_ENUM定义通用枚举,NS_OPTIONS定义位移枚举,详见位移枚举NS_OPTIONS详解

delegate

  • Delegate做后缀,示例:UIScrollViewDelegate
  • @optional修饰可选实现的方法,用@required(默认值)修饰必须实现的方法
  • 类的实例必须为代理方法的参数之一
    • 如果只有一个参数,方法名要符合实际含义,示例:- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
    • 如果有两个及以上参数,以类的名字开头,以表明此方法是属于哪个类的,示例:- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
  • 当你的代理的方法过多, 可以拆分数据部分逻辑部分, 数据部分用DataSource做后缀,示例:UITableViewDataSource,逻辑部分以Delegate做后缀,示例:UITableViewDelegate
  • 代理定义中使用didwill来表达已发生的变化 或 将要发生的变化

方法

  • 方法名用小驼峰式命名
  • 方法名不要使用new作为前缀
  • 不要使用and来连接属性参数
  • 如果方法描述两种独立的行为,使用and来串接它们
  • 方法实现时,如果参数过长,则令每个参数占用一行,以冒号对齐
// ------------- 不要使用 and 来连接属性参数 -------------
// 错误示范
- (void)openURL:(NSURL *)url andOptions:(NSDictionary<UIApplicationOpenExternalURLOptionsKey, id> *)options andCompletionHandler:(void (^ __nullable)(BOOL success))completion {
    
}
// 正确示范
- (void)openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenExternalURLOptionsKey, id> *)options completionHandler:(void (^ __nullable)(BOOL success))completion {
    
}

// ------------- 表示对象行为的方法示范 -------------
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
    
}

// ------------- 对象初始化方法定义示范 -------------
+ (instancetype)arrayWithObject:(id)anObject {
    
}
- (instancetype)initWithObject:(id)anObject {
    
}

// ------------- 如果方法描述两种独立的行为,使用and来串接它们 -------------
- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(KeyType key, id obj, BOOL *stop))block {
    
}

// ------------- 方法实现时,如果参数过长,则令每个参数占用一行,以冒号对齐 -------------
- (void)addObserver:(id)observer
           selector:(SEL)aSelector
               name:(nullable NSNotificationName)aName
             object:(nullable id)anObject {
    
}

代码注释

注释规范

  • 优秀的代码大部分是可以自描述的,完全可以用代码本身来表达它到底在干什么,而不需要注释的辅助。
  • 即使代码有自描述,以下三种情况也必须写好注释:
    • 公共接口(注释是用来快速告诉阅读代码的人,当前类实现什么功能)
    • 涉及到专业知识的代码(注释要说明实现原理和思想)
    • 容易产生歧义的代码(严格来说,容易让人产生歧义的代码是不允许存在的
    • 备注:除了上述三种情况,如果别人还是只能依靠注释才能读懂你的代码,就要反思你写的代码了
  • 对于注释的内容,相对于做了什么,更应该说明为什么这么做

import注释

  • 如果有一个以上的import语句,就要对这些头文件进行分组
  • Controller中
// 分类

// 工具类

// Controllers

// Views

// Models

// Managers
  • View中
// 分类

// 工具类

// Views

// Models

属性注释

  • 使用快捷键command+option+/即可自动生成注释模板,直接看示例:
/// 账户名称
@property (nonatomic, copy) NSString *account;

方法声明的注释

  • 使用快捷键command+option+/即可自动生成注释模板,直接看示例:
/// <#Description#>
/// @param anObject <#anObject description#>
/// @param index <#index description#>
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
    
}

代码块注释

  • 单行的用//+空格开头
  • 多行的采用/** */注释

TODO

  • 使用//TODO:来标记一些 未完成 的地方,这里的 TODO 和 // 之间的空格就不需要

代码格式

指针 * 的位置

  • 靠近变量,示例:NSString *_userName;

方法的声明(定义)

  • 在 - 、+ 和 返回值 之间留一个空格,方法名和返回值之间不留空格,方法名和参数之间不留空格,示例:- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index { };

代码缩进

  • 在 Xcode > Preferences > Text Editing 将 Tab 和 Indent都设置为4个空格
  • 多个方法的声明(定义),Method1 与 Method2 之间空一行
  • 一元运算符与变量之间没有空格,示例:!varName;
  • 二元运算符与变量之间必须有空格,示例:(逻辑运算) ? 选项1 : 选项2;

不要出现一行多句代码

controller中的方法分组

#pragma mark - Life Cycle Methods
// 这里是控制器的生命周期方法汇总
// 不要在viewDidLoad方法里写view的初始化逻辑,封装到属性中,这里只做addSubViews的操作

#pragma mark - Intial Methods
// 这里是初始化方法汇总

#pragma mark - Network Methods
// 这里是网络请求方法汇总

#pragma mark - Override Methods
// 这里是重载的父类的方法汇总

#pragma mark - Event Response Methods
// 这里是事件方法汇总,比如:按钮点击事件,手势响应方法,定时器响应方法等

#pragma mark - UITableViewDataSource

#pragma mark - UITableViewDelegate
// 这里是代理相关的方法,可以是【系统代理方法】或者【自定义的代理方法】
// 这里【必须】写上代理名称,方便别人查看

#pragma mark - Public Methods
// 这里是对外公开的方法汇总

#pragma mark - Private Methods
// 一般情况这种私有方法分类是不应该出现的,如果一个方法实在在上面的分类中找不到放的位置就放到这里吧

#pragma mark - getters and setters
// 这里是一些属性的读写方法,之所以放到最后是为了不至于因为这里的属性太多导致主要代码被挤到很后面
  • 控制器中视图的生命周期的各个阶段适合做的事情
    • viewDidload
      • 在此方法里只做addSubview的事情,subView的初始化放到getter中去做,这样职责比较清晰
      • 不要updateViewConstraints方法里做add constraints,建议在此方法创建Constraints并添加,但是最好将创建并添加Constraints封装到一个方法(如:- (void)layoutPageSubviews{ })中,然后在viewDidload调用此方法,避免viewDidload里代码行数太多
    • viewWillAppear
      • 更新Form数据
      • 缺点:pop回来也会更新数据,会导致网络请求增加
    • viewWillLayoutSubviews or viewDidLayoutSubviews
      • 在这里设置布局
    • viewDidAppear
      • 做Notification的监听之类的事情
    • 如果控制器view是UIScrollView及其子控件,那么viewWillLayoutSubviewsviewDidLayoutSubview调用的非常频繁,因为UIScrollView及其子控件在导航控制器中受contentInset属性的影响导致布局改变,就会调用viewWillLayoutSubviewsviewDidLayoutSubview

view中的方法分组

#pragma mark - Life Cycle Methods
// 这里是view的生命周期方法汇总

#pragma mark - Intial Methods
// 这里是初始化方法汇总

#pragma mark - Override Methods
// 这里是重载的父类的方法汇总

#pragma mark - Event Response Methods
// 这里是事件方法汇总,比如:按钮点击事件,手势响应方法,定时器响应方法等

#pragma mark - Public Methods
// 这里是对外公开的方法汇总

#pragma mark - Private Methods
// 一般情况这种私有方法分类是不应该出现的,如果一个方法实在在上面的分类中找不到放的位置就放到这里吧

#pragma mark - getters and setters
// 这里是一些属性的读写方法,之所以放到最后是为了不至于因为这里的属性太多导致主要代码被挤到很后面

大括号写法规范

  • 首先看一下苹果默认生成的代码中大括号的写法
- (void)viewDidLoad {
    [super viewDidLoad];
}
  • 对于其他使用场景左括号跟在第一行后边,留一个空格,如下示范
    if (<#condition#>) {
        <#statements#>
    } else {
        <#statements#>
    }
    
    while (<#condition#>) {
        <#statements#>
    }

编码规范

if语句

  • 不要使用过多的分支,要善于使用return来提前返回错误的情况,把最正确的情况放到最后返回,示例:
    image.png
  • 条件过多,过长的时候应该换行


    image.png
  • 条件语句的判断建议:变量在右,常量在左


    image.png

for语句

  • 示范
    for (<#type *object#> in <#collection#>) {
        <#statements#>
    }
  • 尽量使用for in循环语句

switch语句

  • 示范
    switch (<#expression#>) {
        case <#constant#>:
            <#statements#>
            break;
            
        default:
            break;
    }
  • 对于switch语句中的各个case中的业务逻辑语句大于一句的需要使用大括号阔起来
    switch (<#expression#>) {
        case <#constant#>: {
            <#statements#>
        }
            break;
            
        default: {
            
        }
            break;
    }
  • 使用枚举类型时,不能有default分支,因为在switch语句使用枚举类型的时候,如果使用了default分支,新增枚举类型时就无法通过编译器来检查到新增的类型
  • 除了使用枚举类型以外,都必须有default分支

函数

  • 一个函数只做一件事(单一原则)
  • 对输入参数的正确性和有效性进行检查,参数错误立即返回,要善于使用return来提前返回错误的情况,把最正确的情况放到最后返回
  • 如果在不同的函数内部有相同的功能,应该把相同的功能抽取出来单独作为另一个函数
  • 将函数内部比较复杂的逻辑提取出来作为单独的函数

去除iOS项目中无用的警告

切记不是所有警告都可以直接忽略的

  • 只屏蔽无关紧要的警告,目的是让我们更加快速找到需要修复的警告
  • 有些警告是代码编写本身有误,可能引起Bug,需要及时修复

执行代码诊断命令

  • 在Xcode中运行Build & Analyze(⌘⇧B)后你会得到的惊人结果
  • 这是Clang 的更细腻,更深沉一面的功能
  • Clang是 C / Objective-C 的前端的 LLVM 编译器。
  • Clang对 Objective-C 的语义和语法有着深刻的理解,而且更重要的原因是现在 Objective-C 已经是这样一个有能力的语言了。

打开Treat Warnings as Errors配置

  • Build Settings搜索Treat Warnings as Errors并设置为YES
  • 设置-Weverything标志
  • 这样设置后大部分项目是无法编译过的,可以有针对性的进行优化,我个人支持这个建议,并鼓励其他开发者更严肃的对待编译警告

去除pod库的警告

  • 在podfile文件中添加如下配置
# 忽略所有警告
inhibit_all_warnings!

# 忽略指定库的警告
pod 'AFNetworking', :inhibit_warnings => true
  • 然后执行:pod install

警告:Pointer is missing a nullability type specifier

  • 苹果提供了两个宏来去除此类警告
  • 使用此宏包住多个属性使其具备nonnull(不可空),然后仅对需要nullable(可空)的改下就行
NS_ASSUME_NONNULL_BEGIN
coding...
NS_ASSUME_NONNULL_END 
  • 使用方法:在.h文件的头部和尾部添加两个宏
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
@interface XXXModel : NSObject

@end
NS_ASSUME_NONNULL_BEGIN
  • 使用了上面的宏后出现警告Null passed to a callee that requires a non-null argument,对需要nullable(可空)的改下就可以去除此警告

打开Treat Incompatible Pointer Type Warnings as Errors开关

  • 开启后类型不兼容会报错,而不是警告

去除directory not found for option警告

  • TARGETS选在对应的项目
  • Build Settings里找到Library Search PathsFramework Search Paths删除找不到的路径即可

去除This block declaration is not a prototype警告

  • Build Settings里找到Strict Prototypes设置为NO即可

关闭工程中指定类型的警告的设置步骤

  • 选中指定类型的警告,选择Reveal in Log,如下图操作
    右键Reveal in Log查看指定类型的警告
  • 则会显示下图


    指定类型的警告
  • [-Wshorten-64-to-32]中括号中的就是警告类型
  • -W表示打开指定类型的警告
  • -Wno-表示关闭指定类型的警告
  • -W换成-Wno-变成-Wno-shorten-64-to-32
  • 将此类型的警告的忽略配置添加到Other Warning Flags中,如下图
    忽略指定类型的警告

如何避免误使用高版本API导致的崩溃问题

  • 打开-Wunguarded-availability在调用高版本API时候报warning,为避免warning过多而忽视,用-Werror-unguarded-availability标记强制编译不过
    使用高版本API检测配置
  • 如果代码本身安全(使用了respondsToSelector:保护),可以用下面两种方式去除警告
    • 方式一
    // 忽略警告:误使用高版本API版
    #define K_Warning_Ignored_Start_ApiCheck _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunguarded-availability\"")
    
    // 这里写忽略警告的code
    
    #define K_Warning_Ignored_End_ApiCheck _Pragma("clang diagnostic pop")
    
    • 方式二@available
    if (@available(iOS 8.0, *)) {
        // 这里写忽略警告的code
    }
    
  • 针对pod需要在.podspec文件中添加compiler_flags配置

至此,编码规范大致写完,后续持续更新...

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • iOS编程规范0规范 0.1前言 为􏰀高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可 测试、高效...
    iOS行者阅读 4,435评论 21 35
  • iOS代码规范 一、前言 本规范基于Google Objective-C Style Guide和百度Object...
    CoderHw阅读 895评论 0 7
  • 一、命名规范 1、统一要求含义清楚,尽量做到不需要注释也能了解其作用,若做不到,就加注释,使用全称,不使用缩写。 ...
    Untils阅读 544评论 0 0
  • 做人该不该有功利心? 前段日子,我从一个朋友那里得知,有一位我所敬重的前辈对我的评价是功利心太重。 功利心是什么?...
    大海怪阅读 508评论 1 3
  • 今天豁出去了,就是叫我下岗也得把满腹的冤屈一肚子苦水倒一倒,把人快憋死了! 在汽车家族中谁最漂亮,脑残的人都知道是...
    西安吴墨阅读 177评论 0 0