zoukankan      html  css  js  c++  java
  • iOS 代码规范

    概述

    命名的好坏在开发中往往也不怎么重视,毕竟差的命名也不会影响程序逻辑。但是不好的命名在大项目中带来的隐形维护成本是相当高的,这些在项目开始时可能还很难察觉,而后来会陷入前仆后继的维护困境中。我们往往非常重视项目逻辑的复杂性,却不能好好的把“简单”的命名做好。其实,如果简单的东西都做不好,那么做出再复杂的东西那也是垃圾。

    命名规范

    分类(类别)命名

    与类命名相同,此外需添加要扩展的类名和“+”

    举例:NSString+URLEncoding

    协议(委托)命名

    与类命名相同,此外需添加“Delegate”后缀

    举例:ReplyViewDelegate

    方法命名

    首字母小写,之后每个单词首字母都大写

    方法名使用动词短语

    举例:- (void)setupPostWithValue:(int)value

    “要什么”往往被胡乱命名为get开头的方法。首先get是一个动词,所以它还是“做什么”或者说“做的是要什么”。那么get方法不要用于返回对象,但它可用于参数。

    - (XXItem *)getItemAtIndex:(NSUInteger)index                  //Bad!! 不规范的命名
    - (XXItem *)itemAtIndex:(NSUInteger)index                     //Good, 命名清晰
    - (void)getItem:(XXItem **)outItem atIndex:(NSUInteger)index  //比较符合规范,但第二种更好。

    参数命名

    首字母小写,之后每个单词首字母都大写

    每个参数前要加参数的名称提示

    举例:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    - (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender

    对象命名

    采用修饰+类型的方式

    举例:

    titleLabel    //表示标题的label,  是UILabel类型
    confirmButton //表示确认的button, 是UIButton类型

    图片命名

    使用英文,全部小写 ,添加模块名作为前缀,避免冲突 。图片应该与类文件一样,按模块分组放置

    举例:

    Home(界面名称)_(功能属性简写+描述).png

    如: home_btn_recommended.png 

    或:

    compose_mentionbutton_background@2x.png

    compose_mentionbutton_background_highlighted@2x.png

    分组命名

    使用英文,首字母大写,之后每个单词首字母都大写

    每个分组使用模块的名字

    使用的开源库统一放在“Library”分组下

    使用的公共组件统一放在“Common”分组下

    使用资源统一放在"Resource"分组下,包括文件、音频、图片、证书等

    编码规范 

    编码规范简单来说就是为了保证写出来的代码具备三个原则:可复用, 易维护, 可扩展. 这其实也是面向对象的基本原则. 可复用, 简单来说就是不要写重复的代码, 有重复的部分要尽量封装起来重用。

    判断nil或者YES/NO

    推荐:

    if (someObject) { ... } 
    if (!someObject) { ... }

    不推荐:

    if (someObject == YES) { ...} 
    if (someObject != nil) { ...}

    if (someObject == YES)容易误写成赋值语句

    条件赋值

    推荐:

    result = object ? : [self createObject];

    不推荐:

    result = object ? object : [self createObject];

    如果是存在就赋值本身, 简洁。

    BOOL赋值

    推荐:

    BOOL isAdult = age > 18;

    不推荐:

    BOOL isAdult;
    if (age > 18)
    {
        isAdult = YES;
    }
    else
    {
        isAdult = NO;
    }

    拒绝死值

    推荐:

    if (car == Car.Nissan)
    or
    const int adultAge = 18; 
    if (age > adultAge) { ... }

    不推荐:

    if (carName == "Nissan")
    or
    if (age > 18) { ... }

    死值每次修改的时候容易被遗忘, 地方多了找起来就悲剧了. 而且定义成枚举或者static可以让错误发生在编译阶段. 另外仅仅看到一个数字, 完全不知道这个数字代表的意义. 纳尼?

    复杂的条件判断

    推荐:

    if ([self canDeleteJob:job]) { ... }     
        
    - (BOOL)canDeleteJob:(Job *)job
    {
        BOOL invalidJobState = job.JobState == JobState.New
                              || job.JobState == JobState.Submitted
                              || job.JobState == JobState.Expired;
        BOOL invalidJob = job.JobTitle && job.JobTitle.length;
         
        return invalidJobState || invalidJob;
    }

    不推荐:

    if (job.JobState == JobState.New
        || job.JobState == JobState.Submitted
        || job.JobState == JobState.Expired
        || (job.JobTitle && job.JobTitle.length))
    {
        //....
    }

    清晰明了, 每个函数DO ONE THING!

    嵌套判断

    推荐:

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

    不推荐:

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

    一旦发现某个条件不符合, 立即返回, 条理更清晰。

    所有的逻辑块必须使用花括号包围,即使条件体只需编写一行代码也必须使用花括号

    推荐:

    if (!error) {
        return success;
    }

    不推荐:

    if (!error)
        return success;
    ...
    if (!error) return success;

    参数过多

    推荐:

    - (void)registerUser(User *user)
    {
         // to do...    
    }

    不推荐:

    - (void)registerUserName:(NSString *)userName
                    password:(NSString *)password 
                       email:(NSString *)email
    {
         // to do...
    }

    当发现实现某一功能需要传递的参数太多时, 就预示着你应该聚合成一个model类了...这样代码更整洁, 也不容易因为参数太多导致出错。

    点标记语法

    属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法。

    推荐:

    view.backgroundColor = [UIColor orangeColor];
    [UIApplication sharedApplication].delegate;

    不推荐:

    [view setBackgroundColor:[UIColor orangeColor]];
    UIApplication.sharedApplication.delegate;

    枚举

    枚举使用Objective-C方式来定义,枚举命名是 类前缀+枚举名,枚举值要加枚举名。

    举例:

    typedef NS_ENUM(NSUInteger, HGMachineState) {
        HGMachineStateNone,
        HGMachineStateIdle,
        HGMachineStateRunning,
        HGMachineStatePaused
    };

    常量

    常量应该类名称+“骆峰式”单词大写。

    推荐:

    static const NSTimeInterval HGSignInViewControllerFadeOutAnimationDuration = 0.4;

    不推荐:

    static const NSTimeInterval fadeOutTime = 0.4;

    常数是优于串联字符串或数字的,允许多个地方使用常用变量,可以迅速改变不需要查找和替换。常量应该声明为静态常量而不使用宏定义,除非明确需要定义一个宏。

    推荐:

    static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";
    static const CGFloat ZOCImageThumbnailHeight = 50.0f;

    不推荐:

    #define CompanyName @"Apple Inc."
    #define magicNumber 42

    单例模式

    使用GCD代替使用sharedInstance,每次调用+ (id)sharedInstance函数都会付出取锁的代价。

    推荐:

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

    不推荐:

    + (instancetype)sharedInstance
    {
        static id sharedInstance;
        @synchronized(self) {
            if (sharedInstance == nil) {
                sharedInstance = [[MyClass alloc] init];
            }
        }
        return sharedInstance;
    }

    代理

    定义一个协议是 类名+Delegate,并要使用weak 弱指针,协议使用可选@optional

    @class ZOCSignUpViewController;
    
    @protocol ZOCSignUpViewControllerDelegate <NSObject>
    @required
    - (void)signUpViewController:(ZOCSignUpViewController *)controller didProvideSignUpInfo:(NSDictionary *);
    @optional
    - (void)signUpViewControllerDidPressSignUpButton:(ZOCSignUpViewController *)controller;
    @end
    
    
    @interface ZOCSignUpViewController : UIViewController
    
    @property (nonatomic, weak) id<ZOCSignUpViewControllerDelegate> delegate;
    
    @end

    在发送委托代理方法之前,一定要先检查该委托方法已经被实现(否则会崩溃)。

    if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) {
        [self.delegate signUpViewControllerDidPressSignUpButton:self];
    }

    动画

    推荐

    [UIView animateWithDuration:1.0
                     animations:^{
                         // something
                     }
                     completion:^(BOOL finished) {
                         // something
                     }];

    不推荐

    [UIView animateWithDuration:1.0 animations:^{
        // something 
    } completion:^(BOOL finished) {
        // something
    }];

    Pragma Mark

    使用“#pargma mark - ”实现方法的分组。建议按下面几点单独分组:

    1.功能分组

    2.代理协议实现分组

    3.重写父类方法

    - (void)dealloc { /* ... */ }
    - (instancetype)init { /* ... */ }
    
    #pragma mark - View Lifecycle
    
    - (void)viewDidLoad { /* ... */ }
    - (void)viewWillAppear:(BOOL)animated { /* ... */ }
    - (void)didReceiveMemoryWarning { /* ... */ }
    
    #pragma mark - Custom Accessors
    
    - (void)setCustomProperty:(id)value { /* ... */ }
    - (id)customProperty { /* ... */ }
    
    #pragma mark - IBActions
    
    - (IBAction)submitData:(id)sender { /* ... */ }
    
    #pragma mark - Public
    
    - (void)publicMethod { /* ... */ }
    
    #pragma mark - Private
    
    - (void)zoc_privateMethod { /* ... */ }
    
    #pragma mark - UITableViewDataSource
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }
    
    #pragma mark - ZOCSuperclass
    
    // ... overridden methods from ZOCSuperclass
    
    #pragma mark - NSObject
    
    - (NSString *)description { /* ... */ }

    抽象方法定义

    在Componens中有很多的抽象类,因为Objective-C没有语法限定抽象类,所以我们约定一下抽象类的注释和声明方法。
    在类注释中声明该类为抽象类,抽象方法必须为公开方法,并添加#pragma标记注释 
    @interface TestClass : NSObject
    
    #pragma mark - Abstract Method
    
    //抽象方法
    -(void)doWork;
    
    @end

    抽象类不允许被实例化,所以需要在init方法中添加判断代码

    @implementation TestClass
    
    - (id)init {
        if( [self class] == [TestClass class]) {
            @throw [NSException exceptionWithName:@"抽象类无法实例化" reason:@"抽象类无法实例化: TestClass" userInfo:nil];
        }
        else {
            self = [super init];
            if(self){
                
            }
            return self;
        }
    }
    
    #pragma mark - Abstract Method
    
    - (void)doWork {
        @throw [NSException exceptionWithName:@"抽象方法没有被实现" reason:@"抽象方法没有被实现: doWork" userInfo:nil];
    }
    
    @end

    参数链接:

    https://github.com/objc-zen/objc-zen-book

    http://www.cocoachina.com/ios/20151014/13678.html

    http://www.cocoachina.com/ios/20151118/14242.html

  • 相关阅读:
    Numpy学习1
    spark SQL学习(综合案例-日志分析)
    spark SQL学习(认识spark SQL)
    spark SQL学习(案例-统计每日销售)
    spark SQL学习(案例-统计每日uv)
    spark SQL学习(spark连接 mysql)
    spark SQL学习(spark连接hive)
    spark SQL学习(数据源之json)
    常用的Java工具类——十六种
    Idea格式化快捷键无效,没反应
  • 原文地址:https://www.cnblogs.com/jys509/p/5002502.html
Copyright © 2011-2022 走看看