iOS学习笔记IOS文章收集iOS开发_性能优化

如何让你的代码写的更优雅?(持续更新)

2017-07-06  本文已影响1228人  Link913

前言

以前写代码也仅仅是注意C语言一些基本的规范还有驼峰命名法什么的,后来看了一些书籍,也写过不少代码,review过不少别人的代码,所以把自己的一些感悟记一下吧.在本文的最后我会把我们老大写的集团的iOS端编码规范放一下,第一部分的那个新特性的规范的demo就是把我之前的代码改了下,哈哈.

这篇文章会持续更新,这里我会把我文章最后除了附录中的集团的代码规范外自己的东西会写出来.再看这篇文章前推荐看两本书Objective-C高级编程 iOS与OS X多线程和内存管理,Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法,第二本书读完写了篇读书笔记,这是链接

自己的一些编码技巧和代码规范(2017.7.6版)

tableview中cell的复用id

控件可以这样命名,这样联想起来更加的方便

比如说一个姓名label你可以起名为lb_name,这样当你想调用他的时候是不是更方便呢?公司现在的要求是写成nameLabel的.

条件语句或者参数过多时请换行对齐

        [[KLPrestoClient prestoClient] postBaseInfoMationWithEducation:_postParaFlags.education
                                                         monthlyIncome:_postParaFlags.monthlyIncome
                                                        professionType:_postParaFlags.jobInfo
                                                              marriage:_postParaFlags.marriage
                                                              cityName:_cityNameStr
                                                           cityAddress:_addressStr
                                                              latitude:_latitudeStr
                                                             longitude:_longitudeStr
                                                       isProvidentFund:providentFundModel.selectedIndex
                                                          eMailAddress:_EMailAddrStr
                                                      censusIsLiveCity:censusModel.selectedIndex
                                                                 isHud:YES
                                                               success:^(BaseModel *model) {
                                                                   
            if ([model.status isEqualToString:@"000"]) {
                
                //上传数据成功
                [self.navigationController popViewControllerAnimated:YES];
                
            } else {
                
            }
            
        } failture:^(id error) {
        }];

尽量多的利用参数和返回值,尽量不要使用全局变量

    /**
     对城市按照首字母分组
     */
    - (NSArray *)p_makeCityGroup:(NSArray *)cityArray{
        NSMutableArray *letterDictArray = [NSMutableArray array];
        //创建26个数组用来存储
        for (int i = 0; i < 26; i ++) {
            NSMutableArray *letterCityArray = [NSMutableArray array];
            [letterDictArray addObject:letterCityArray];
        }
        
        for (CCityModel *model in cityArray) {
            
            //将城市首字母转化为asic码
            int asciiCode = [model.cityCode characterAtIndex:3];
            int index = asciiCode - 97;
            [letterDictArray[index] addObject:model];
        }
        return [letterDictArray copy];
    }

在一些需求巧妙地利用完全初始化方法,不要将不需要外部改变的属性readwrite

    /**
     普通model
     */
    - (instancetype)initNormalModelWithTitle:(NSString *)title answer:(NSString *)answer answerArray:(NSArray *)answerArray {

        return [self initBaseInfomationWithTitle:title
                                          answer:answer
                                   selectedIndex:NO_CHOOSE_ANSWER_INDEX
                                           isMap:NO
                                     answerArray:answerArray
                              isTwoChooseBtnCell:NO
                              isEMailAddressCell:NO];
    }

    /**
     带地图的model
     */
    - (instancetype)initMapModelWithTitle:(NSString *)title answer:(NSString *)answer {
        
        return [self initBaseInfomationWithTitle:title
                                          answer:answer
                                   selectedIndex:NO_CHOOSE_ANSWER_INDEX
                                           isMap:YES
                                     answerArray:nil
                              isTwoChooseBtnCell:NO
                              isEMailAddressCell:NO];
    }

    /**
     二选一model
     */
    - (instancetype)initTwoChooseOneModelWithTitle:(NSString *)title answerArray:(NSArray *)answerArray {
        //index传-1表示二选一未选择
        return [self initBaseInfomationWithTitle:title
                                          answer:@""
                                   selectedIndex:NO_CHOOSE_ANSWER_INDEX
                                           isMap:NO
                                     answerArray:answerArray
                              isTwoChooseBtnCell:YES
                              isEMailAddressCell:NO];
    }

    /**
     带邮箱的model
     */
    - (instancetype)initEMailModelWithTitle:(NSString *)title defaultAnswer:(NSString *)defaultAnswer{
        //index传-1表示未输入
        return [self initBaseInfomationWithTitle:title
                                          answer:defaultAnswer
                                   selectedIndex:NO_CHOOSE_ANSWER_INDEX
                                           isMap:NO
                                     answerArray:nil
                              isTwoChooseBtnCell:NO
                              isEMailAddressCell:YES];
    }

    /**
     完全初始化
     */
    - (instancetype)initBaseInfomationWithTitle:(NSString *)title answer:(NSString *)answer selectedIndex:(NSInteger)selectedIndex isMap:(BOOL)isMap answerArray:(NSArray *)answerArray isTwoChooseBtnCell:(BOOL)isTwoChooseBtnCell isEMailAddressCell:(BOOL)isEMailAddressCell{
        if (self = [super init]) {
            _title = title;
            _answer = answer;
            _selectedIndex = selectedIndex;
            _isMap = isMap;
            _answerArray = answerArray;
            _isTwoChooseBtnCell = isTwoChooseBtnCell;
            _isEMailAddressCell = isEMailAddressCell;
        }
        return self;
    }

    @end

附录(集团iOS端代码规范)

Objective-C 编程风格指南

Controller注释、命名示例

//
//  JLaunchViewController.m
//  J1000
//
//  Created by 作者姓名 on 17/2/8.
//  Copyright © 2017年 user. All rights reserved.
//

#import "JLaunchViewController.h"

@interface JLaunchViewController ()<UIScrollViewDelegate>

/*
 * 引导页位置指示器
 */
@property (weak, nonatomic) IBOutlet UIPageControl *dotPageControl;

/*
 * 引导图容器
 */
@property (weak, nonatomic) IBOutlet UIScrollView *intrScrollView;

/*
 * 进入按钮
 */
@property (weak, nonatomic) IBOutlet UIButton *nextButton;

@end

@implementation JLaunchViewController{
    /*
     * 引导图数组
     */
    NSMutableArray * _imageArray;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 初始化界面
    [self initView];
    
    // 数据绑定()
    [self dataBind];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - UI
/*
 * 初始化界面
 */
- (void)initView{
    
    // 设置scrollView属性(隐藏水平滚动条,边框不反弹、整页翻动、关联代理类)
    self.intrScrollView.showsHorizontalScrollIndicator = NO;
    self.intrScrollView.bounces = NO;
    self.intrScrollView.pagingEnabled = YES;
    self.intrScrollView.delegate = self;
    
    // 设置pageControl属性(设置指示圆点默认色值与选中色值、背景颜色、整页翻动后再切换当前位置)
    self.dotPageControl.currentPageIndicatorTintColor = [UIColor blackColor];
    self.dotPageControl.pageIndicatorTintColor = [UIColor whiteColor];
    self.dotPageControl.backgroundColor = [UIColor clearColor];
    self.dotPageControl.defersCurrentPageDisplay = YES;
    
    // 默认隐藏底部按钮
    self.nextButton.hidden = YES;
}

/*
 * 数据绑定
 */
- (void)dataBind{

    // 测试
    _imageArray =  [[NSMutableArray alloc]initWithObjects:@1, @2, @2, @2, @2, nil];
    
    // 设置ScrollView内容的宽度与高度
    self.intrScrollView.contentSize = CGSizeMake(ScreenWidth * _imageArray.count, ScreenHeight);
    
    // 循环添加图片
    for (int i = 0; i< _imageArray.count ; i++) {
        UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(ScreenWidth * i, 0, ScreenWidth, ScreenHeight)];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        imageView.backgroundColor = i == 0 ? [UIColor greenColor] : [UIColor orangeColor];
        [self.intrScrollView addSubview:imageView];
    }
    
    // 设置pageControl圆点总数与当前位置
    self.dotPageControl.numberOfPages = _imageArray.count;
    self.dotPageControl.currentPage = 0;
    
}
#pragma mark - target
/*
 * 进入按钮单击事件处理函数
 */
- (IBAction)didClickNextBtn:(id)sender {
    
    if (self.loginSwitchVCBlock) {
        self.loginSwitchVCBlock();
    }
}

#pragma mark - delegate
/*
 * 滚动视图滚动事件处理函数
 */
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    // 当拖动偏移量超过半屏时切换圆点位置
    self.dotPageControl.currentPage = (int) (scrollView.contentOffset.x + ScreenWidth/2) /ScreenWidth;
    
    // 判断是否隐藏进入按钮
    self.nextButton.hidden = !(self.dotPageControl.currentPage == _imageArray.count - 1);
}

@end

Xcode项目

简写

名称 缩写
infomation info
message msg
descriptation desc

类的命名

要求 例如
ViewController 使用Controller做后缀 例子: DDFHomeController
View 使用View做后缀 例子: DDFAlertView
UITableCell 使用Cell做后缀 例子: DDFNewsCell
Protocol 使用Delegate或者DataSource作为后缀 例子: UITableViewDelegate
Model 使用model作为后缀 例子: DDFDataModel
单例 manager 例子: DDFUserInfoManager
类的拓展 类名+项目简写+extra 例子: NSString+DDFExtra

宏命名

要求 例如
宏定义方法 小驼峰命名 例子: getImageUrl(url) [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",DDFBaseUrl,url]]
宏定义常量 遵循大驼峰命名(开头以项目简写) 例子:#define DDFWidth self.frame.size.width, KScreenWidth [UIScreen mainScreen].bouds.size.width

变量的命名

要求 例如
用修饰+类型的方式 (小驼峰式命名) UIButton *settingButton

property变量

要求 例如
小驼峰式命名 @property (strong, nonatomic) NSSNumber *userId;
NSString 使用copy @property (copy, nonatomic) NSString *userName;
所有属性特性应该显式地列出来 @property (weak, nonatomic) IBOutlet UIView *containerView;

图片命名

要求 例如
功能名称_____控件类型 ___自定义参数 share_____btn _weixin

枚举类型

typedef NS_ENUM(NSInteger, DDFRequestState) {
    DDFRequestStateInactive,
    DDFRequestStateLoading
}; 

方法命名

- (void)setExampleText:(NSString *)text image:(UIImage *)image;
+ (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;

代理命名

- (BOOL)tableView:(NSTableView*)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender 
           openFile:(NSString *)filename;
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;

代码组织

  1. 懒加载
  2. 控制器生命周期。
  3. 私有方法
  4. 通知方法
  5. 代理方法。
  6. 公共方法。
  7. 触发事件。

#pragma mark - lazy

- (NSArray *)array {
    if(!_array) {
    
    }
    return _array;
}



#pragma mark - Lifecycle

- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}

#pragma mark - Private

- (void)privateMethod {}

#pragma mark - NSCopying
- (void)didReceiveNotification {}

#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate

#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}

#pragma mark - Public
- (void)publicMethod {}
#pragma mark - IBActions

- (IBAction)submitData:(id)sender {}

点表示法

应该:
NSInteger arrayCount = self.array.count;
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

不应该:
NSInteger arrayCount = [self.array count];
[view setBackgroundColor:[UIColor orangeColor]];
[[UIApplication sharedApplication] delegate];

空格

- (void)methodName:(NSString *)string;

if (a < b) {
    // something
}

(someValue > 100)? YES : NO

Literals字面量

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018; 

Case语句

switch (condition) {
  case 1:
    // ...
    break;
  case 2: {
    // ...
    // Multi-line example using braces
    break;
  }
  case 3:
    // ...
    break;
  default: 
    // ...
    break;
}

switch (condition) {
  case 1:
    // ** fall-through! **
  case 2:
    // code executed for values 1 and 2
    break;
  default: 
    // ...
    break;
}

布尔变量

if (someObject) {}
if (![anotherObject boolValue]) {}
@property (assign, getter=isEditable) BOOL editable;

条件语句

应该:
if (!error) {
  return success;
}
不应该:
if (!error)
  return success;
  
 if (!error) return success;

三元操作符

应该:
result = a > b ? x : y; 
不应该:
result = a > b ? x = c > d ? c : d : y; 

注释

上一篇下一篇

猜你喜欢

热点阅读