1、在一个类的头文件中尽量少引用其他头文件

  如果Person.h 引入了EmployeePerson.h,而后续又有其他类如Human.h又引入了Person.h, 那么EmployeePerson.h也会一并被引入到Human.h.如此往复,引入的头文件会越来越多,也会引入一些根本不需要的头文件,增加编译时间。

如何解决头文件中引用其他头文件:

1)用向前声明的方法@className来解决头文件被直接引用的问题。向前引用只是告诉编译器有一个类名 className在该类中需要用到,但是不需要知道className中的全部细节。

2)也可以使用#import "className.h"

有一些原则尽量延迟引入头文件,如能在实现文件.m中引入就不要在头文件.h中引入.

有一点例外,就是如果当前类遵守了一个协议,则必须引入协议所在的头文件(#import),而不能只用“向前声明”@className

如:

#import “Drawable.h”

@interface Rectangle : Shape<Drawable>//这里的 协议 <Drawable>所在的类必须用 #import "Drawable.h"而不能用@Drawable;

@end

2、多用字面量语法,少用与之等价的正规方法。

  起开始,我也觉得,用正规语法不是跟安全可靠吗?其实不然,用字面量语法简洁,且在字面量语法创建数组和字典时如果当中有nil会在写代码时直接报错,防止因nil出现的问题。用正规语法时,数组和字典当中可以有nil。

  OC 2.0 中的新特性,就是可以用字面量来初始化自定义对象了。不用繁琐的语法也能创建和初始化对象。

例如 NSString *someString = @"Effective Objective-C 2.0";

字面数值:

整数、浮点数、布尔值封装到OC对象中。

正规方法:

NSNumber *someNumber = [NSNumber numberWithInt:1];

简化方法(语法糖):

NSNumber *someNumber = @1;

NSNumber *intNumber = @1;

NSNumber *floatNumber = @2.5f;

NSNumber *doubleNumber = @3.14.159;

NSNumber *boolNumber = @YES;

NSNumber *charNumber = @'a';

数组:

常规方法:

NSArray *animals = [NSArray arrayWithObject:@"cat",@"dog",@"mouse",@"badger",nil];

NSString *dog = [animals objectAtIndex:1];

如果是可变数组,[mutableArray replaceObjectAtIndex:1 withObject:@"dog"];

字面量:

NSArray *animals = @[@"cat",@"dog",@"mouse",@"badger"];

NSString *dog = animail[1];

如果是可变数组,mutableArray[1] = @"dog";

字典

常规方法:(先值后键,反人类)

NSDictinary *personData = [NSDitionary dictionaryWithObjectsAndKeys:@"Wang",@"firstName",@"Jarvis",@"lastName",[NSNumber numberWithInt:28],@"age",nil];

如果是可变字典,[mutableDictionary setObject:@"dive" forKey:@"lastName"];

字面量:(先键后值)

NSDictonary *personData = @{@"firstName":@"Wang",@"lastName":@"Jarvis",@"age":@28};

如果是可变字典,mutableDictionary[@"lastName"] = @"dive";

注意:字面量语法创建出来的对象,除字符串以外,都必须属于Foundation框架。如果想创建自定义子类的实例,必须采用非字面量语法。

字面量语法创建的字符串、数组、字典对象都不可变,可用mutableCopy 方法把它转化为可变对象。

3、多用类型常量,少用#define预处理指令。

例如:

#define ANIMATIN_DURATION 0.3

该预处理指令会把代码中的 ANIMATIN_DURATION 全部替换为字符串 0.3,没有类型信息。

优化:

static const NSTimeInterval kAnimationDuration = 0.3;

这样既包含了类型信息,利于代码阅读,他表示一个时间间隔,所以用了TimeInterval类型。

变量声明一定要同时用 static 和 const 关键字。

static 修饰符意味着该变量仅在定义此变量的编译单元中可见,即定义此变量的.m文件。

const 修饰符意味着该变量不可修改。

如果同时用了这两个修饰符,那么编译器根本不会创建符号,而是像#define预处理指令一样,把遇到的变量都替换为常量值。

有时候要对外公开某个常量,比如要在代码中调用通知中心(NSNotificationCenter)通知其他类,用一个对象来派发通知,另其他欲接收通知的对象向该对象注册,这样就能实现此功能了。派发通知时,需要使用字符串来表示此项通知的名字,而这个名字就可以声明为一个外部可用的常值变量(constant variable)。这样的话,注册者不需要知道实际字符串值,只需要以常值变量来注册自己想要接收的通知即可。

此类常量需要放在“全局符号表“(global symbol table)中,以便可以在定义该常量的编译单元之外使用。定义方式:

//.h

extern NSString *const NotificationName;

//.m

NSString *const NotificationName= @"NotificationName";

发现该全局常值变量实在头文件中声明,在实现文件中定义的。对已声明的解读,从右向左,NotificationName是一个常量,而这个常量是一个指针,指向NSString对象。编译器看到extern关键字,就能明白如何在引入此头文件的代码中处理该常量 ,这个关键字告诉编译器,在全局符号表中将会有一个叫NotificationName的符号,也就是说,编译器无需查看其定义,即允许代码使用此常量。因为它知道,当链接层二进制文件之后,肯定能找到这个常量。

此类常量必须被定义,且只能定义一次。

4、用枚举表示状态、选项、状态码

1)表示状态

某个对象所经历的各种状态,就可以定义为一个简单的枚举集(enumeration set),比如套接字链接(socket connection)的状态:

enum ConnectionState {

  ConnectionStateDisconnected,

  ConnectionStateConnecting,

  ConnectionStateConnected,

};

定义枚举变量的方式不太简洁,要依如下语法编写:

enum ConnectionState state = ConnectionStateDisconnected;

若不想每次都敲 enum 只敲ConnectiontState。可以使用typedef关键字重新定义枚举类型。

type enum ConnectionState ConnectionState;

这时候,就可以这样定义一个枚举变量了、

ConnectionState state = ConnectionStateDisconnected;

C++11标准修订了枚举的某些特性,其中一项改动就是:可以指明何种”底层数据类型“(underlying type)来保存枚举类型的变量。这样做的好处是,可以向前声明枚举变量了,若不指定底层数据类型,则无法向前声明枚举类型,因为编译器不清楚底层数据类型的大小,所以在用到此枚举类型时,也就不知道究竟该给变量分配多少空间。

指定底层数据类型所用的语法是:

enum ConnectionState ConnectionState : NSInteger{

  ConnectionStateDisconnected,

  ConnectionStateConnecting,

  ConnectionStateConnected,

};

还可以不使用编译器分配的序号,而是手工指定某个枚举成员所对应的值。

enum ConnectionState ConnectionState {

  ConnectionStateDisconnected = 1,

  ConnectionStateConnecting,

  ConnectionStateConnected,

};

2)定义选项

若这些选项可以彼此组合,则更应该如此、只要枚举定义的对,就可以通过”按位或操作符“(bitwise OR operator)来组合。

iOS UI框架中,用此类枚举表示某个视图应该如何在水平或垂直方向上调整大小。

enum UIViewAutoresizing {

  UIViewAutoresizingNone          = 0,

  UIViewAutoresizingFlexibleLeftMargin     = 1 << 0,

  UIViewAutoresizingFlexibleWidth        = 1 << 1,

  UIViewAutoresizingFlexibleRightMargin      = 1 << 2,

  UIViewAutoresizingFlexibleTopMargin         = 1 << 3,

  UIViewAutoresizingFlexibleHight         =  1 << 4,

   UIViewAutoresizingFlexibleBottomMargin     = 1 << 5,

}

这样

UIViewAutoresizingFlexibleLeftMargin   启用时 枚举变量的值二进制表示就是  000001

UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHight  二进制表示就是 010010

Foundation 框架中定义了一些辅助的宏,这些宏定义枚举类型,也可以指定底层数据类型。这些宏具备向后兼容。

typedef NS_ENUM(NSUinteger, ConnectionState) {

  ConnectionStateDisconnected,

  ConnectionStateConnecting,

  ConnectionStateConnected,

};

或者

typedef NS_OPTION(NSUInteger, ConnectionState){

  PermittedDirectionUp      = 1 <<0,

  PermittedDirectionDown      = 1 << 1,

  PermittedDirectionLeft       = 1 << 2,

  PermittedDirectionRight       = 1 << 3,

}

3)用于switch语法

switch(_currentState){

  ConnectionStateDisconnected:

  //handel

    break;

  ConnectionStateConnecting:

//handel

    break;

  ConnectionStateConnected:

//handel

    break;

//不要用default: 这样,在枚举变量新增时就能立即被Xcode检查到,方便及时更新该处代码。

}

Effective Objective-C 笔记之熟悉OC的更多相关文章

  1. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

  2. Effective STL读书笔记

    Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...

  3. Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  4. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  5. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  6. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  7. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  8. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  9. Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor

    Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...

随机推荐

  1. WinForm中实现HotKey

    最近在写一个游戏辅助工具,来点Win变成的总结 主要用了RegisterHotKey:UnregisterHotKey:两个winAPI 以下代码来自stackoverflow新增了一个HotKeyM ...

  2. iOS 将Excel导入到SQLite3的过程

    1.打开Excel表格,另存为.csv文件 2.打开SQLite3,选择File -> Import -> other... 3.在弹出的文件选择框中选择步骤1保存的.cvs文件 4在弹出 ...

  3. Mac下Intellij IDea发布JavaWeb项目 详解一 (1、新建JavaEE Project并进行相应设置 2、配置tomcat)

    IDEA中 javaWeb项目的创建和tomcat配置(完整) 1.先新建JavaEE Project并进行相应设置 2.在配置tomcat Step1 新建JavaEE Project并进行相应设置 ...

  4. 转:桩模块 stub 和驱动模块 driver

    迷惑我很久的stub的概念,今天终于看到觉得靠谱的了,原文地址:http://xyzhaoangela.blog.hexun.com/14208786_d.html 桩模块stub:集成测试前要为被测 ...

  5. 通过设置P3P头来实现跨域访问COOKIE

    通过设置P3P头来实现跨域访问COOKIE 实际工作中,类似这样的要求很多,比如说,我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是PASSPORT的功能. 我只写一个大 ...

  6. 嵌入式系统C编程之堆栈回溯(二)

    前言 本文作为<嵌入式系统C编程之堆栈回溯>的补充版.文中涉及的代码运行环境如下: 一  异常信号 信号就是软件中断,用于向正在运行的程序(进程)发送有关异步事件发生的信息.Linux应用 ...

  7. 今日Java——Cay Horstmann访谈

    这是本人在InfoQ中文站审校的文章,原文链接是:http://www.infoq.com/cn/articles/java_cay_horstmann,感觉内容很不错,分享给大家看看. 近日Info ...

  8. Qt编写视频播放器(vlc内核)

    在研究qt+vlc的过程中,就想直接做个播放器用于独立的项目,vlc还支持硬件加速,不过部分电脑硬件不支持除外.用vlc的内核写播放器就是快,直接调用api就行,逻辑处理和ui展示基本上分分钟的事情, ...

  9. Android NDK学习(3)使用Javah命令生成JNI头文件 .

    转:http://www.cnblogs.com/fww330666557/archive/2012/12/14/2817387.html 第一步: 在Eclipse中创建android项目,并声明N ...

  10. Android 线程与主线程

    网络连接需要时间.Web服务器可能需要1~2秒的时间来响应,文件下载则耗时更久.考虑到这个因素,Android禁止任何主线程网络连接行为.即使强行为之,Android也会抛出NetworkOnMain ...