iOS小技能:编码规范、第三方库管理规范及常见问题

399 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

引言

iOS小技能:第三方库管理规范 https://blog.csdn.net/z929118967/article/details/119206808

编码风格Apple官方文档:

The Objective-C Programming Language :

developer.apple.com/library/mac…

Cocoa Fundamentals Guide :

developer.apple.com/legacy/libr…

Coding Guidelines for Cocoa :

developer.apple.com/library/mac…

iOS App Programming Guide:

developer.apple.com/library/ios…

I Objective-C编码规范

1.1 代码组织

Xcode编码器将 #pragma 作为预处理指令,#pragma 在编译时进行计算。但它并不像如 #ifdef...#endif 之类的宏,#pragma 的使用方式不会改变你的应用运行时的行为。相反的,#pragma 声明主要由 Xcode 用来完成两个主要任务:整理代码和防止编译器警告

  1. 整理代码: 在函数分组和protocol/delegate实现中使用#pragma mark 来分类方法

  1. Xcode 调试技巧:忽略警告(屏蔽clang warning)

a、全局/局部屏蔽的方法 b、忽略 CocoaPods 第三方库警告 c、clang/Lexer/Parser 警告清单

———————————————— 版权声明:本文为CSDN博主「iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载>请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/z929118967/article/details/77678850

1.2 注释

当需要注释时,注释应该用来解释这段特殊代码为什么要这样做。

任何被使用的注释都必须保持最新或被删除。

1.3 命名

  • 方法和变量命名: Apple命名规则尽可能坚持,长的,描述性的方法和变量命名
UIButton *settingsButton; 

  • 常量:应该使用驼峰式命名规则,所有的单词首字母大写和加上与类名有关的前缀。
static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;  
// 使用字符串常量来代替宏的使用
//定义const 全局常量  ,保证只在一处定义,多处进行引用
////#define HWClientId @""//宏会在编译时,将所有引用宏变量的地方,进行值的替换,造成很多相同的临时字面量,浪费内存
//NSString * const HWClientId = @"";// 全局的const常量代替宏常量,节省内存空间。内存只有一份

  • 属性:属性也是使用驼峰式,但首单词的首字母小写。

对属性使用auto-synthesis( 自动合成),而不是手动编写@synthesize语句,除非特殊需要

@property (strong, nonatomic) NSString *descriptiveVariableName; 

  • 局部变量不应该包含下划线。(为了和实例变量进行区别)

  • 点语法应该总是被用来访问和修改属性

    self.isfooterRereshing = NO;

  • 所有属性特性应该显式地列出来,有助于阅读代码。

属性特性的顺序是storage、atomicity,与Interface Builder连接UI元素时自动生成代码一致。

@interface KNTutorial : NSObject 

 @property (strong, nonatomic) NSString *tutorialName;//所有属性特性应该显式地列出来,有助于阅读代码。属性特性的顺序是storage、atomicity,与Interface Builder连接UI元素时自动生成代码一致。

 @end


  • NSString应该使用copy而不是strong的属性特性。

因为即使在你你声明一个NSString的属性的时候,有人可能传入一个NSMutableString的实例,然后在你没有注意的情况下修改它。

1.4 不允许直接修改对象的结构体属性的成员;

OC中,不予许直接修改“对象”(iconButton)的“结构体属性”(frame)的“成员”(origin);但是允许修改结构体属性的成员

- (void)setY:(CGFloat)y{
    CGRect frame = self.frame;
    frame.origin.y = y;//允许修改结构体属性的成员
    self.frame = frame;
}

1.5 使用CGGeometry操作frame

1.6 布尔值

  • Objective-C使用YES和NO。

因为true和false应该只在CoreFoundation,C或C++代码使用。

  • 既然nil解析成NO,所以没有必要在条件语句比较。 不要拿某样东西直接与YES比较,因为YES被定义为1

1.7 switch

当在switch使用枚举类型时,’default’是不需要的。

1. 8 避免if语句的嵌套

将逻辑处理放置于if结构之外

采用的场景是对必填字段的判断

- (void)someMethod { 
 if (![someOther boolValue]) { 
 return; } 
//Do something important  
} 

例子

    if(self.settlementStr.integerValue !=  SettlementTypeEnum4Public){

        if(![QCT_Common bankCardluhmCheckWithCardNo:_jskhTextF.text]){
            
            [SVProgressHUD showInfoWithStatus:@"请输入正确的结算卡号"];

            
            return ;
            
            
        }

    }
    
    
    
    
    
    
    if (_cardNameTextF.text.length < 1 ) {
       return [SVProgressHUD showInfoWithStatus:@"请输入账户名称"];
        
        
    }
// 请求接口提交信息

避免以下代码的出现

    [self.view endEditing:YES];
    if (ymmTextF.text.length < 1) {
        [SVProgressHUD showErrorWithStatus:@"请输入原密码."];
    } else if (xmmTextF.text.length < 1) {
        [SVProgressHUD showErrorWithStatus:@"请输入新密码."];
    } else if (qrmmTextF.text.length < 1) {
        [SVProgressHUD showErrorWithStatus:@"请输入确认密码."];
        
        } else if (![xmmTextF.text isEqualToString: qrmmTextF.text]) {

        [SVProgressHUD showErrorWithStatus:@"两次密码输入不一致."];
    } else {// 请求接口
}

1.9 错误处理

避免通过判断NSError进行错误处理

NSError *error; 
[self trySomethingWithError:&error]; 
if (error) {
 // Handle Error  
} 

应用判断方法的BOOL返回值

NSError *error; 
if (![self trySomethingWithError:&error]) {
 // Handle Error  
} 

1.10 单例模式

单例对象应该使用线程安全模式来创建共享实例。

+ (instancetype)sharedInstance { 
 static id sharedInstance = nil; 
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); 
 return sharedInstance; 
} 

【使用GCD结合宏来实现单例】 使用条件编译进行ARC、MRC的适配

kunnan.blog.csdn.net/article/det…

1.11 Xcode工程

  • 物理文件应该与Xcode工程文件保持同步

任何Xcode分组的创建应该在文件系统的文件体现。

  • 代码不仅是根据类型来分组,而且还可以根据功能来分组,这样代码更加清晰。

  • 在target的Build Settings打开”Treat Warnings as Errors,和启用以下Other Warning Flags。如果你需要忽略特殊的警告,使用Clang’s pragma feature。

Xcode 调试技巧:忽略警告(屏蔽clang warning)

II 、性能相关

2.1 全局的const常量代替宏常量,节省内存空间。

  • 使用字符串常量来代替宏的使用

1、定义const 全局常量 ,保证只在一处定义,多处进行引用 2、全局的const常量代替宏常量,节省内存空间。内存只有一份



#define KNClientId @""//宏会在编译时,将所有引用宏变量的地方,进行值的替换,造成很多相同的临时字面量,浪费内存
NSString * const KNClientId = @"";// 全局的const常量代替宏常量,节省内存空间。内存只有一份

2.2 深入理解MRC和ARC内存管理机制

  1. 需要释放的资源:imageCache、queue、operations、view、通知监听者的移除、销毁soundID
  2. 释放的方法:dealloc 、applicationDidReceiveMemoryWarning、didReceiveMemoryWarning
  3. 凡是函数名中带有create、copy、new、retain等字眼的,都应该在不需要它的时候进行release。 GCD的数据类型在ARC环境下不需要进行release;而CF的数据类型在ARC、MRC环境下都需要做release的。

III 常见问题

3.1 get 和post 布尔值参数处理

iOS网络请求小知识: get 和post 布尔值参数处理(get请求对应的0和1,post对应true/false:若服务端Bool 参数没有同时支持这两种格式,就需要处理)

———————————————— 版权声明:本文为CSDN博主「iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/z929118967/article/details/105138207

3.2 Cocoa naming

Property follows Cocoa naming convention for returning 'owned' objects

不能以new 关键字开头定义属性

正确的属性定义