iOS 代码书写的整洁与美化

Posted Xiejunyi12

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 代码书写的整洁与美化相关的知识,希望对你有一定的参考价值。

1.善用#pragma mark

利用pragma mark xxx 分割你的代码
例如一个视图控制器可以分割为如下部分

  1. Class Methods 类方法
  2. View Life Cycle 控制器视图生命周期
  3. Setter 方法
  4. Getter 方法
  5. Actions Button 的行动
  6. Help Methods 辅助方法
  7. Deleagte/DataSource 协议

这时候,方法列表是这样的

多用Setter Getter 方法

显然,把一些代码写在Setter Getter 方法中 更方便检索

Getter

通过Getter 方法,我把对imageView的初始化和配置全部集中在Getter方法中。

争论
if(!_xxx)… 这个判断可能会影响及其细微的性能,也可以去掉这个判断,看个人喜好来.

#pragma mark Getter

- (UIImageView *)imageView 
    if (!_imageView) 
        _imageView = [[UIImageView alloc] init];
        _imageView.backgroundColor = [UIColor redColor];
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
    
    return _imageView;

Setter

Setter 方法,我经常会将设置某些属性时,连带的操作写在其中。
这对封装很有必要。

这段代码,我在给image 属性赋值的时候,就连带着给self.imageView.image 属性赋值。
避免了暴露imageView


//public  @property (nonatomic, strong) UIImage *image;
//private  @property (nonatomic, strong) UIImageView *imageView;

#pragma mark Setter

- (void)setImage:(UIImage *)image 
    _image = image;
    self.imageView.image = image;

KVO相较于Setter 方法,可以提供更多的功能,来解决一些问题.
但是KVO让代码过于凌乱,或许可以试试Reactive Cocoa,可是学习它值得吗,调试很让人头疼…值得思考

2.好的书写风格

属性声明问题

@property (原子性,存储属性,访问限制) NSString *example;

if语句

if (x.text.length > 0) 
    self.placeholderLabel.alpha = 0;
 else 
    self.placeholderLabel.alpha = 1;
  

而不是
if(x.text.length > 0)
    self.placeholderLabel.alpha = 0;
else
    self.placeholderLabel.alpha = 1;

名称写法

  1. 类 大驼峰
  2. 实例 小驼峰
  3. OC方法 小驼峰
  4. C方法 大驼峰
  5. 宏定义 大驼峰

括号

尽量使用括号使得语句清晰,而不是根据运算符优先级判断。

//避免出现这种写法
xx&xx||xx&xx

方法书写

- (void)method 



而不是

-(void)method

枚举

使用NS_ENUM
typedef NS_ENUM(NSUInteger, XJYLineChartType) 
    //仅有线和横竖坐标
    XJYLineChartTypeSimple,
    //有表格 default
    XJYLineChartTypeNormal,
    //有数值
    XJYLineChartTypeDetail,
;

而不是 enum
typedef enum DrawLineType
    PointType = 0,
    BrokenType ,
    BezierType,
DrowLineType;

3.注释

对外暴露的接口

/// 注释/**
 注释
 */

代码内部注释

由于Objective-C 变量,方法名称是自解释的,所以只需在一些关键部位加上注释
1. 代码功能的核心
2. 提供视觉上的提醒
3. 较难理解的部分

及时删除注释掉的代码部分

既然该段代码没有用处,就不应该来干扰程序员阅读代码。及时删掉即可。

函数代码间空行

  1. 根据功能块空行
  2. 跟注释结合空行
  3. 不要频繁空行

好的例子

// Will undo the runtime changes made.
static void aspect_cleanupHookedClassAndSelector(NSObject *self, SEL selector) 
    NSCParameterAssert(self);
    NSCParameterAssert(selector);

    Class klass = object_getClass(self);
    BOOL isMetaClass = class_isMetaClass(klass);
    if (isMetaClass) 
        klass = (Class)self;
    

    // Check if the method is marked as forwarded and undo that.
    Method targetMethod = class_getInstanceMethod(klass, selector);
    IMP targetMethodIMP = method_getImplementation(targetMethod);
    if (aspect_isMsgForwardIMP(targetMethodIMP)) 
        // Restore the original method implementation.
        const char *typeEncoding = method_getTypeEncoding(targetMethod);
        SEL aliasSelector = aspect_aliasForSelector(selector);
        Method originalMethod = class_getInstanceMethod(klass, aliasSelector);
        IMP originalIMP = method_getImplementation(originalMethod);
        NSCAssert(originalMethod, @"Original implementation for %@ not found %@ on %@", NSStringFromSelector(selector), NSStringFromSelector(aliasSelector), klass);

        class_replaceMethod(klass, selector, originalIMP, typeEncoding);
        AspectLog(@"Aspects: Removed hook for -[%@ %@].", klass, NSStringFromSelector(selector));
    

    // Deregister global tracked selector
    aspect_deregisterTrackedSelector(self, selector);

    // Get the aspect container and check if there are any hooks remaining. Clean up if there are not.
    AspectsContainer *container = aspect_getContainerForObject(self, selector);
    if (!container.hasAspects) 
        // Destroy the container
        aspect_destroyContainerForObject(self, selector);

        // Figure out how the class was modified to undo the changes.
        NSString *className = NSStringFromClass(klass);
        if ([className hasSuffix:AspectsSubclassSuffix]) 
            Class originalClass = NSClassFromString([className stringByReplacingOccurrencesOfString:AspectsSubclassSuffix withString:@""]);
            NSCAssert(originalClass != nil, @"Original class must exist");
            object_setClass(self, originalClass);
            AspectLog(@"Aspects: %@ has been restored.", NSStringFromClass(originalClass));

            // We can only dispose the class pair if we can ensure that no instances exist using our subclass.
            // Since we don't globally track this, we can't ensure this - but there's also not much overhead in keeping it around.
            //objc_disposeClassPair(object.class);
        else 
            // Class is most likely swizzled in place. Undo that.
            if (isMetaClass) 
                aspect_undoSwizzleClassInPlace((Class)self);
            else if (self.class != klass) 
                aspect_undoSwizzleClassInPlace(klass);
            
        
    

好的编程思想

函数式编程的一些思想很好

1. 抽取方法中没有”副作用”

所谓”副作用”(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。

2.引用透明

引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或”状态”,只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的

Block,Notification,Deleagte的选择

Block和Deleagte 之间的选择

尽量使用代理,Block 虽然省事,但是后患无穷啊。

Notification

一对多通信的最佳选择

要在代码中的两个不相关的模块中传递消息时,通知机制是非常好的工具。通知机制广播消息,当消息内容丰富而且无需指望接收者一定要关注的话这一招特别有用。
通知可以用来发送任意消息,甚至可以包含一个 userInfo 字典。你也可以继承 NSNotification 写一个自己的通知类来自定义行为。通知的独特之处在于,发送者和接收者不需要相互知道对方,所以通知可以被用来在不同的相隔很远的模块之间传递消息。这就意味着这种消息传递是单向的,我们不能回复一个通知。

以上是关于iOS 代码书写的整洁与美化的主要内容,如果未能解决你的问题,请参考以下文章

《代码整洁之道》精读与演绎之五 整洁类的书写准则

《代码整洁之道》读后总结

15 个书写 JavaScript 代码的整洁之道(实用!)

Matlab代码书写规范

Matlab代码书写规范

Matlab代码书写规范