《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个方法》

《Effective Objective-C 2.0编写高质量i

2018-11-05  本文已影响0人  Mr_WangZz

1. 了解OC语言的起源

知识点

  1. OC: 消息型类型,使用消息结构,其运行时所应执行的代码由 运行环境 决定;
  2. 而使用函数调用的语言,则由 编译器 决定。
  3. 对象所占内存总是分配在 堆空间,而绝不会在栈上。
  4. 上保存的是指向对象的指针。
  5. 定义里不含 “ * ” 的变量(非对象类型),可能会被分配到 栈 上,如CGRect。它是C 结构体。

要点总结

2. 在类的头文件中尽量少引入其他头文件

想要在一个文件中引入另一个(如Model:Person.h)类,且只需要知道类名,可以:

//#import "Person.h"
@class Person;

这种写法,叫“向前声明”该类。总结:

除非有必要,否则不要引入头文件。一般来说,应在某个类的 (xxxx.h)头文件 中使用 向前声明 来提及别的类,并在 (xxxx.m)实现文件 中引入那些类的头文件。这样做 可以尽量降低类之间的耦合(coupling)

有时无法使用向前声明,如声明某个类遵循一项协议。这种情况下,尽量把 “该类遵循某协议” 的这条声明移至 “class-continuation分类” 中。如果不行的话,就把协议单独放在一个头文件中,然后将其引入。见27条

3. 多用字面量语法,少用与之等价的方法

知识点

  1. 使用字面量语法(Literal syntax)可以缩短源代码长度,使之更为易读。如
/** 1 */
NSString *someString1 = [[NSString alloc] initWithString:@"I'm wanazen"];
//可简写为:
NSString *someString2 = @"I'm wanazen";

/** 2 */
NSNumber *someNumber = [NSNumber numberWithInt:1];
//可简写为:
NSNumber *intNumber = @1;
NSNumber *doubleNumber = @3.14159;
NSNumber *boolNumber = @YES;
NSNumber *charNumber = @'a';

int x = 5;
float y = 8.99f
NSNumber *expressionNumber = @(x * y) ;
/** 创建 */
NSArray *animals = [NSArray arrayWithObjects:@"cat", @"dog", @"mouse", nil];
//可简写成
NSArray *animalsNew = @[@"cat", @"dog", @"mouse"];

/** 取值 */
NSString *cat = [animals objectAtIndex:0];
//可简写为
NSString *catNew = animalsNew[i];
/** 创建 */
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"Wanazen",@"firstName", @"Lona", @"lastName", [NSNumber numberWithInt:2019], @"year"];
//可简写为
NSDictionary *dic2 = @[@"firstName":@"Wanazen", @"lastName":@"Lona", @"year":@2019];

/** 取值 */
NSString *firstName = [dic objectForKey:@"firstName"];
//可简写为
NSString *firstName2 = dic[@"firstName"];

//赋值操作可以写成字面量。
  1. 字面量语法实际上只是一种“语法糖”(syntax sugar),其效果等于是 先创建了一个对象,然后执行了那些简写之前的操作。
  2. 数组、字典等一旦有值为nil时,可能会抛出异常。
  3. 限制:除了字符串之外,所创建出来的对象必须属于Foundation框架才行。
  4. 使用字面量创建出来的字符串、数组、字典对象都是不可变的(immutable)。若想创建可变版本的对象,则需要复制一份。
//虽然会多调用一个方法,还要在创建一个对象,不过优大于劣
NSMutableArray *mutableArray = [[@1, @2, @3, @4] mutableCopy];

要点总结:

4. 多用类型常量,少用#define预处理指令

优化前的目标代码:

#define ANIMATION_DURATION 0.3
  1. 只在文件内(.m)使用 的写法:
/*
升级的写法. 
根据实际数据类型声明常量。
const:不允许修改。修改后编译器报错
static:局限在编译单元.m文件中
*/
static const NSTimInterval kAnimationDuration = 0.3;
  1. 在被引入的文件同样生效(对外开放) 的写法:
//在.h文件 - 声明

// LoginManager.h
#import <Foundation/Foundation.h>

extern NSString *const LoginManagerDidLoginNotification;

@interface LoginManager()
***
@end

//在.m文件 - 定义
// LoginManager.m

#import "LoginManager.h"

NSString *const LoginManagerDidLoginNotification = @"LoginManagerDidLoginNotification";

@implementation LoginManager
***
@end

常用的命名法:

要点总结:

5. 用枚举表示状态、选项、状态码

由于 OC 基于 C 语言,所以 C 语言有的功能它都有。枚举(ENUM),是一种常量的命名方式。

/**
 C语言下的语法
*/
enum EOCConnectionStateConnectionState {
    EOCConnectionStateDisConnected = 1,
    EOCConnectionStateConnecting,
    EOCConnectionStateConnected,    
};

/**
 OC中
*/
typedef NS_ENUM(NSUInteger, EOCConnectionState) {
    EOCConnectionStateDisConnected,
    EOCConnectionStateConnecting,
    EOCConnectionStateConnected,    
};

//适用于 按位或操作来组合 的枚举
typedef NS_OPTIONS(NSUInteger, EOCPermittedDirection) {
    EOCPermittedDirectionUp = 1 << 0,
    EOCPermittedDirectionDown = 1 << 1,
    EOCPermittedDirectionLeft = 1 << 2,
    EOCPermittedDirectionRight = 1 << 3,
};
要点总结:

系列文章

上一篇下一篇

猜你喜欢

热点阅读