1.精简代码, 返回最后一句的值,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染。但缺点是可读性比较差

NSURL *url = ({ NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];

[NSURL URLWithString:urlString];

});

2.关于编译器:关闭警告:

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

[myObj performSelector:mySelector withObject:name];

#pragma clang diagnostic pop

3.忽略没用的变量

#pragma unused (foo)

明确定义错误和警告

#error Whoa, buddy, you need to check for zero here!

#warning Dude, don't compare floating point numbers like this!

4.避免循环引用

  • 如果【block内部】使用【外部声明的强引用】访问【对象A】, 那么【block内部】会自动产生一个【强引用】指向【对象A】

  • 如果【block内部】使用【外部声明的弱引用】访问【对象A】, 那么【block内部】会自动产生一个【弱引用】指向【对象A】

__weak typeof(self) weakSelf = self;

dispatch_block_t block = ^{

[weakSelf doSomething]; // weakSelf != nil

// preemption, weakSelf turned nil

[weakSelf doSomethingElse]; // weakSelf == nil

};

最好这样调用:

__weak typeof(self) weakSelf = self;

myObj.myBlock = ^{

__strong typeof(self) strongSelf = weakSelf;

if (strongSelf) {

[strongSelf doSomething]; // strongSelf != nil

// preemption, strongSelf still not nil(抢占的时候,strongSelf 还是非 nil 的)

[strongSelf doSomethingElse]; // strongSelf != nil }

else { // Probably nothing... return;

}

};

5.宏要写成大写,至少要有大写,全部小写有时候书写不提示参数;

6.建议书写枚举模仿苹果——在列出枚举内容的同时绑定了枚举数据类型NSUInteger,这样带来的好处是增强的类型检查和更好的代码可读性,示例:

// 不推荐写法

typedef enum{

UIControlStateNormal       = 0,

UIControlStateHighlighted  = 1 << 0,

UIControlStateDisabled     = 1 << 1,

} UIControlState;

// 推荐写法

typedef NS_OPTIONS(NSUInteger, UIControlState) {

UIControlStateNormal       = 0,

UIControlStateHighlighted  = 1 << 0,

UIControlStateDisabled     = 1 << 1,

};

7.建议加载xib,xib名称用NSStringFromClass(),避免书写错误

// 推荐写法

[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([DXRecommendTagVCell class]) bundle:nil] forCellReuseIdentifier:ID];

// 不推荐写法

[self.tableView registerNib:[UINib nibWithNibName:@"DXRecommendTagVCell" bundle:nil] forCellReuseIdentifier:ID];

8.场景需求:在继承中,凡是要求子类重写父类的方法必须先调用父类的这个方法进行初始化操作;建议:父类的方法名后面加上NS_REQUIRES_SUPER; 子类重写这个方法就会自动警告提示要调用这个super方法,示例代码

// 注意:父类中的方法加`NS_REQUIRES_SUPER`,子类重写才有警告提示

- (void)prepare NS_REQUIRES_SUPER;

9.建议书写属性名不要和系统一样,避免发生莫名其妙的问题;特别注意的是label;属性名不要写成textLabel

10.项目中添加plist类型文件,不要命名为info.plist,以防止和系统自带的文件重名,发生莫名其妙的问题;

11.如果控制器已经加载过,就不用再次加载,优化性能

if (vc.isViewLoaded) return;

12.id类型属性不能用点语法,调用get方法只能用中括号调用,[id 方法名],利用iOS9新特性泛型就可以; 比如数组;

@property (nonatomic,strong) NSMutableArray *topicsM;

13.如果不是属性,尽量不要点语法,一个老程序员的建议;

14.使用第三方框架,尽量不要更改内部文件,而应该再次封装,个性定制;

15.判断if书写方式

建议这样写

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

if (indexPath.row == 0) return 44;

if (indexPath.row == 1) return 80;

if (indexPath.row == 2) return 50;

return 44;

}

而不是

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

if (indexPath.row == 0) {

return 44;

}else if (indexPath.row == 1){

return 80;

}else if (indexPath.row == 2){

return 50;

}else{

return 44;

}

}

16.接手一个新项目,快速的调试,查看某个模块或者方法的作用,需要注释掉一个方法,或者某个代码块,直接写return;而不是全选,注释掉;

比如:查看这个方法loadNewRecommendTags作用

- (void)loadNewRecommendTags

{

return;

[SVProgressHUD show];

// 取消之前的任务

[self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];

NSMutableDictionary *params = [NSMutableDictionary dictionary];

params[@"a"] = @"tag_recommend";

params[@"c"] = @"topic";

params[@"action"] = @"sub";

[self.manager GET:DXCommonUrlPath parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {

self.recommendTag = [DXRecommendTag mj_objectArrayWithKeyValuesArray:responseObject];

[self.tableView reloadData];

[SVProgressHUD dismiss];

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

DXLog(@"%@",error);

[SVProgressHUD dismiss];

}];

}

17.在一个自定义的View中,或者自定义cell中,modal出一个控制器建议:

[UIApplication sharedApplication].keyWindow.rootViewController

代替

self.window.rootViewController,因为程序可能不止一个window,self.window可能不是主窗口;

18.建议:用CGSizeZero 代替 CGSizeMake(0,0);

CGRectZero代替CGRectMake(0, 0, 0, 0);

CGPointZero代替CGPointMake(0, 0)

19.监听键盘的通知建议:

UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification

而不是,下面代码;因为键盘可能因为改变输入法,切换成表情输入,切换成英文,那么frame可能会变高,变矮,不一定会发出下面这些通知,但是肯定会发上面的通知

UIKIT_EXTERN?NSString *const UIKeyboardWillShowNotification;

UIKIT_EXTERN?NSString *const UIKeyboardDidShowNotification;

UIKIT_EXTERN?NSString *const UIKeyboardWillHideNotification;

UIKIT_EXTERN?NSString *const UIKeyboardDidHideNotification;

20.发布通知的字符串常量规范,建议模仿苹果;如上键盘的通知的书写,加上const 保证字符串不可更改,以Notification结尾,一看就知道是通知;应尽量保证可读性,不要怕句子太长;

NSString *const buttonDidClickNotification = @"buttonDidClickNotification";

21.如果除数为0,iOS8以下会直接报错,(NaN—>Not a Number)iOS9不会,所以应该判断,比如服务器返回图片的宽高,按比例缩放,CGFloat contentH = textW * self.height / self.width;

22.如果声明的属性,只想使用的get方法,不使用set方法,并且不想让外界更改这个属性的值,那么建议在括号里面加readonly;示例:

@property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow;

23.如果属性是BOOL类型,建议在括号中重写get方法名称,以提高可读性,示例代码如上;

24.从系统相册中取照片之前,应该判断系统相册是否可用,如果从相机中拍照获取,要判断相机是否可用

// 判断相册是否可以打开

if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;

// 判断相机是否可以打开

if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return;

25.在导航控制中,或它的子控制器,设置导航栏的标题应该用self.navigationItem.title = @“标题”而不建议self.title = @“标题”;

26.给cell设置分割线,建议用setFrame:通过设置它高度,设置分割线,而不推荐用给cell底部添加一个高度的UIView,这样做增加了一个控件,从性能上来讲,不如用setFrame设置高度

27.大量操作图层会可能造成应用很卡,给用户体验差,所以尽量不要操作图层;比如设置按钮圆角,比如给button设置圆角;

self.loginBtn.layer.cornerRadius = 5;

self.loginBtn.layer.masksToBounds = YES;

28.给分类扩充方法,建议加上前缀,比如第三方框架SDWebImage,这样做跟系统的方法很容易区分开,减少了程序员之间的沟通成本,同理跟分类添加属性(利用运行时),建议加前缀,以防止苹果官方过一段时间添加了一模一样的属性名,比如给UITextField分类添加了placeholderColor这个属性,万一某天官方给placeholder扩充了这个命名一模一样的属性,那么就不好了

29.凡是在storyboard或者xib中给某个控件添加颜色,颜色对角线有分割线,表示可以设置透明度,如果给这个控件设置透明度建议在这里设置,而不是设置alpha,因为设置了alpha,那么上面有文字也会随着透明度变大,而变得不清楚;可以设置background -->other -->opacity

30.整形转化成浮点型,不建议这么写 a / b 1.0,这样写是错误写法,示例1.5 / 2 1.0;根据运算法则,从作到右,0 1.0 == 0,而应该在前面写1.0 1.5 /2;建议直接强转;(double)a/b;

31.抽取方法,或者写工具类,能写类方法,尽量写成类方法,减少了创建对象的步骤,比如给UIView扩充分类加载xib,viewWithXib;

32.耗时操作应该放在子线程,避免卡主主线程,比如计算文件大小,下载大文件,清除缓存;

33.声明一个属性,如果是对象,比如数组,不能以new单词开始,否则直接报错,因为new在OC中是生成一个对象的方法,有特殊含义;比如,

@property (nonatomic,strong) NSMutableArray *newTopicsM;

注意:如果newtopicsM是一个单词(区别于驼峰标志),这样写不会报错;如果是基本数据类型则不会报错,比如

@property (nonatomic,assign) int newNumber;

但是如果一定要写new单词开头的属性,那么声明属性的时候,重写getter方法名称只不过使用getter方法的时候注意下

34.在自定义方法中,and这个词的用法应该保留。它不应该用于多个参数来说明,就像initWithWidth:height以下这个例子:

- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

而不应该

- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;

35.建议POST请求参数字典的写法,这样比较装逼~

// NSDictionaryOfVariableBindings这个宏生成一个字典,这个宏可以生成一个变量名到变量值映射的Dictionary,比如:

NSNumber * packId=@(2);

NSNumber *userId=@(22);

NSNumber *proxyType=@(2);

NSDictionary *param=NSDictionaryOfVariableBindings(packId,userId,proxyType);

iOS中书写代码规范35条小建议的更多相关文章

  1. How Javascript works (Javascript工作原理) (二) 引擎,运行时,如何在 V8 引擎中书写最优代码的 5 条小技巧

    个人总结: 一个Javascript引擎由一个标准解释程序,或者即时编译器来实现. 解释器(Interpreter): 解释一行,执行一行. 编译器(Compiler): 全部编译成机器码,统一执行. ...

  2. 好代码是管出来的——.Net中的代码规范工具及使用

    上一篇文章介绍了编码标准中一些常用的工具,本篇就具体来介绍如何使用它们来完成代码管理. 本文主要内容有: Roslyn简介 开发基于Roslyn的代码分析器 常用的基于Roslyn的代码分析器 在.N ...

  3. Net中的代码规范工具及使用

    Net中的代码规范工具及使用 https://www.cnblogs.com/selimsong/p/9209254.html 上一篇文章介绍了编码标准中一些常用的工具,本篇就具体来介绍如何使用它们来 ...

  4. 去掉vue 中的代码规范检测(Eslint验证)

    去掉vue 中的代码规范检测(Eslint验证): 1.在搭建vue脚手架时提示是否启用eslint检测的. Use ESLint to lint your code? 写 no; 2.如果项目已经生 ...

  5. IOS中的编码规范

    1.指导原则 [原则1-]首先是为人编写程序,其次才是计算机. 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发.测试.生产.用户使用.版本升级和后期维护等长期过程,只有易读.易维护的软件代 ...

  6. PHP中PSR-[0-4]代码规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

  7. iOS OC开发代码规范

    1.变量.类名.函数名 使用驼峰命名法 2.尽量使用完整的单词命名,尽量不采用 缩写单词 3.类名使用大写字母打头,前缀统一加上HH 例如:HHHomePageController 4.类的成员变量使 ...

  8. iOS 中隐藏UITableView最后一条分隔线

    如何优雅的隐藏UITableView中最后一条分割线? 这个问题是很常见,却又不太容易解决的. 可能通常的做法都是隐藏UITableView的分割线,自定义一条. 最近在使用弹出菜单的时候,同样遇到了 ...

  9. IOS中录音后再播放声音太小问题解决

    1.AVAudioSessionCategory说明 1.1 AVAudioSessionCategoryAmbient 或 kAudioSessionCategory_AmbientSound 用于 ...

随机推荐

  1. class和id的区别

    我们平常在用DIV CSS制作Xhtml网页页面时,常会用到class 和id来选择调用CSS样式属性.对学习CSS的新手来说class和id可能比较模糊,同时不知道什么时候该用class,什么时候又 ...

  2. 【Java深入研究】2、JVM类加载机制

    一.先看看编写出的代码的执行过程: 二.研究类加载机制的意义 从上图可以看出,类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类 ...

  3. 半小时C语言题目

    每个5分共100分.错选.多选.少选或不选均不得分. .[单选题]一个C程序的执行是从( ) A:本程序的main函数开始,到main函数结束 B:本程序文件的第一个函数开始,到本程序文件的最后一个函 ...

  4. phpcms v9更改后台文章排序的方法

    后台文章排序怎么才可以按自己输入的数字排列?如按4,3,2,1,从大到小排列?实现方法如下: 修改文件: phpcms\modules\content 中的 content.php 代码如下: $da ...

  5. 剑指offer编程题Java实现——面试题5从头到尾打印链表

    题目描述* 剑指offer面试题5:从尾到头打印链表 输入一个链表的头结点,从尾到头打印出每个结点的值 解决方案一:首先遍历链表的节点后打印,典型的"后进先出",可以使用栈来实现这 ...

  6. java学习笔记——IO流部分

    IO流常用的有:字符流.字节流.缓冲流.序列化.RandomAccessFile类等,以上列出的都是开发中比较常用的. 1.字节流: 字节流包含:FileInputStream/FileOutputS ...

  7. SaberRD之交流分析

    交流分析(AC Analysis)也叫做小信号(Small-Signal)分析,也即分析电路的小信号频率响应,更严谨的定义是:分析工作在直流偏置电压下的非线性电路对于一定频率范围内的输入小信号的系统响 ...

  8. dns服务搭建

    DNS 是域名系统 (Domain Name System) 的缩写,它是由解析器和域名服务器组成的. 域名服务器是指保存有该网络中所有主机的域名和对应IP地址,并具有将域名转换为IP地址功能的服务器 ...

  9. TCP/IP协议(零)TCP/IP参考模型

    我们先浏览一下TCP/IP的参考模型,对网络模型有一个大致的了解,后续着重学习OSI参考模型. TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型. 1.结构 TCP/ ...

  10. keepalived 安装配置

    keepalived介绍 1. keepalived 是lvs 的扩展项目,因此它们之间具备良好的兼容性. 2. 通过对服务器池对象的健康检查,实现对失效机器/服务的故障隔离. 3. 负载均衡器之间的 ...