第三章:接口与API设计

15 用前缀避免命名空间冲突

总结:避免重名符号错误的唯一办法是变相实现命名空间。为所有符号都加上命名前缀。类和分类都应加三字前缀。注意类实现文件中的纯C函数及全局变量,是算作“顶级符号的”(不属于任何类?)。如果用第三方库编写自己的代码,并准备将其再发布为程序库供他人使用,尤其要注意符号问题,应该再加上引用的三方库加上自己的三字前缀。(若自己所开发的程序中用到了第三方库,则应为其中的名称加上前缀)

16 提供全能初始化方法

总结:只有在全能初始化方法中,才会存储内部数据,这样的话,当底层数据存储机制改变时,只需修改此方法的代码就好,无需改动其他初始化方法。有时候需要编写多个全能初始化方法,譬如某个对象的实例有两种完全不同的创建方式,必须分开处理,例如NSCoding,提供序列化机制,对象可以此指明其自身的编码和解码方式,UI框架就广泛运用此机制,NIB和试图(xml)对象之间的转换。在类中提供一个全能初始化方法,并于文档里指明其他初始化方法均应调用此方法。若全能初始化方法与超类不同,则需覆写超类中的对应方法。如果超类的初始化方法不适用于子类,那么应该覆写这个超类方法,并在其中抛出异常。

17 实现description方法

总结:想要在po的时候调试出来重写debugDescription方法。

18 尽量使用不可变对象

总结:当属性是即可读又可写的时候设计出来的类都是可变的。应尽量把对外公布出来的属性设为只读,而且只在确有必要时才将属性对外公布。@property (nonatomic, copy, readonly) NSString *identifier;这个时候不指定内存管理语义也可以,@property (nonatomic, readonly) NSString *identifier;但是此时在外边仍然能通过键值编码设置这些属性值setValue:forKey。不要在返回的对象上查询类型以确定其是否可变,不易从底层直接修改对象中的数据。尽量创建不可变对象。若某属性仅可于对象内部修改,则在分类中将其由readonly属性扩展为readwrite属性。不要把可变的collection作为属性公开,而应提供相关方法以此修改对象中的可变collection。

19 使用清晰而协调的命名方式

总结:驼峰式大小写命名法:方法和变量名,以小写字母开头,其后每个单词首字母大写。 如果方法的返回值是新创建的,那么方法名的首个词应是返回值的类型,除非前面还有修饰语,属性的存取方法不遵循这种命名方式,因为一般认为这些方法不会创建新对象,即使返回拷贝对象。方法名里不要使用缩略后的类型名称。

20 为私有方法名加前缀

总结:私有方法只在实现的时候声明。OC没有办法将方法标为私有,苹果用一个下划线作为私有方法的前缀。不能将方法限定于某个范围内,也许是OC的缺点,然后作为动态方法派发系统这个强大组件的一部分,次特性也带来了诸多好处。

21 理解OC错误模型

总结:OC对异常的处理方法是,只有在极罕见的情况下抛出异常,异常抛出之后无须考虑恢复问题,而且应用程序此时也应该退出。也就是说,不用再编写复杂的异常安全代码了。在出现不那么严重的错误时,令方法返回nil/0,或是使用NSError,以表明其中有错误发生。NSError的用法更加灵活,因为可以由此对象将错误的原因报告给调用者。两种用法,有错误发生时,当前对象会把错误信息经由协议中的某个方法传递给其委托对象- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;或者经由方法的输出参数,返回给调用者- (BOOL)doSomething:(NSError * __autoreleasing*)error;此方法不仅能有普通的返回值,而且还能经由“输出参数”把NSError对象回传给调用者。

NSError *error = nil;

BOOL ret = [object doSomething:&error];表示该操作是成功了还是失败了

if(error){具体错误信息

}

*error = [NSError errorWithDomain:domain code:code userInfo:userInfo];

*error为error参数解引用,就是说error所指的那个指针现在要指向一个新的NSError对象了。在解引用之前必须先保证error参数不是nil,因为空指针解引用会导致“段错误”并使应用程序崩溃。调用者在不关心具体错误时,会给error参数传入Nil。

22 理解NSCopying协议

总结:没有专门深拷贝的协议,所以其具体执行方式由每个类来确定。我们只需决定自己所写的类是否要提供深拷贝方法即可。若想令自己缩写的对象具有拷贝功能,则需实现NSCopying协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现NSCopying与NSMutableCopying协议。复制对象时需决定采用浅拷贝还是深拷贝,一般情况下应该尽量执行浅拷贝。如果你所写的对象需要深拷贝,那么可考虑新增 一个专门执行深拷贝的方法。

{

//    //非容器类对象 对于不可变对象的copy是浅复制,对于不可变对象的mutablecopy是深复制

NSString *string = @"origion";

NSString *stringCopy = [string copy];//得到的是不可变的拷贝

NSMutableString *mstringCopy = [string copy];//浅拷贝

NSMutableString *stringMCopy = [string mutableCopy];

NSMutableString *c = (NSMutableString *)string;//其实还是不可变的

//    //非容器类,对于可变对象的copy和mutablecopy都是深拷贝,但是copy返回的对象是不可变的

NSMutableString *string = [NSMutableString stringWithString: @"origion"];

NSString *stringCopy = [string copy];

NSMutableString *mstringCopy = [string copy];

NSMutableString *stringMCopy = [string mutableCopy];

NSLog(@"");

//    //系统容器类

//copy返回不可变对象,mutablecopy返回可变对象

NSArray *array = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];

NSArray *arrayCopy1 = [array copy];//是和array同一个NSArray对象

//以上两个是指针复制

NSMutableArray *mArrayCopy1 = [array mutableCopy];//这个是对象复制,可以改变其内的元素,删除或添加,但,容器内的元素内容都是指针复制。

NSArray *mArray1 = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];

NSArray *mArrayCopy2 = [mArray1 copy];

NSMutableArray *mArrayCopy1 = [mArray1 mutableCopy];

NSArray *deepCopyArray = [[NSArray alloc]initWithArray:mArray1 copyItems:YES];//也并不是真正意义上的深拷贝,对于其中可变元素是深拷贝,对于其中不可变元素还是指针复制,但官方文档已经将这个方法列为deepcopy,并添加了copy和mutablity的关系说明

NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:mArray1]];//真正意义上的深拷贝

}

effective OC2.0 52阅读笔记(三 接口与API设计)的更多相关文章

  1. effective OC2.0 52阅读笔记(七 系统框架)

    47 熟悉系统框架 总结:将代码封装为动态库,并提供接口的头文件,就是框架.平时的三方应用都用静态库(因为iOS应用程序不允许在其中包含动态库),并不是真正的框架,然而也经常视为框架.例如:NSLin ...

  2. effective OC2.0 52阅读笔记(二 对象、消息、运行期)

    第二章:对象.消息.运行期 6 理解属性这一概念 总结:OC解决硬编码偏移量问题的做法,一种方案是把实例变量当做一种存储偏移量所用的特殊变量,交由类对象保管,偏移量会在运行期查找,叫做稳固的“应用程序 ...

  3. effective OC2.0 52阅读笔记(六 块与大中枢派发)

    派发队列:dispatch_queue 操作队列:NSOperationQueue  组:dispathc_group_t 37 理解“块”这一概念 总结:块就是一个值,且自有其相关类型.块的强大之处 ...

  4. effective OC2.0 52阅读笔记(五 内存管理)

    第五章:内存管理 29 理解引用计数 30 以ARC简化引用计数 总结:ARC通过命名约定将内存管理规则标准化.其他编程语言很少像OC这样强调命名.ARC通过设置全局数据结构(此数据结构的具体内容因处 ...

  5. effective OC2.0 52阅读笔记(四 协议与分类)

    23 通过委托与数据源协议进行对象间通信 总结:委托模式的常规委托模式中,信息从类Class流向受委托者delegate.数据源模式,信息从数据源datasource流向class.数据源和受委托者可 ...

  6. effective OC2.0 52阅读笔记(一 熟悉Objective-C)

    第一章:熟悉Objective-C 1 了解objective-c语言的起源 总结:OC为C语言添加了面向对象的特性,是其超集.采用动态绑定的消息结构而非函数调用,也就是说,要在运行时才检查对象类型及 ...

  7. 第3章 接口与API设计 52条笔记

    第3章 接口与API设计 52条笔记 第15条: 用前缀避免命名空间冲突 Objective-C 没有其他语言那种内置的命名空间机制 .鉴于此,我们在起名时要设法避免潜在的命名冲突,否则很容易就重名了 ...

  8. 论文阅读笔记三:R2CNN:Rotational Region CNN for Orientation Robust Scene Text Detection(CVPR2017)

    进行文本的检测的学习,开始使用的是ctpn网络,由于ctpn只能检测水平的文字,而对场景图片中倾斜的文本无法进行很好的检测,故将网络换为RRCNN(全称如题).小白一枚,这里就将RRCNN的论文拿来拜 ...

  9. Code Complete阅读笔记(三)

    2015-05-26   628   Code-Tuning Techniques    ——Even though a particular technique generally represen ...

随机推荐

  1. android自定义控件(5)-实现ViewPager效果

    对于系统的ViewGroup我们已经是十分熟悉了,最常用的LinearLayout和RelativeLayout几乎是天天要打交道,下面我们就来看看,如何一步一步将其实现: 一.首先当然也是最通常的新 ...

  2. [CentOs7]图形界面

    摘要 为了更方面的看到命令的执行后的效果,感觉安装一个图形界面,学习起来更有感觉.至少知道自己做了哪些事.在刚开始安装虚机的时候,选择了最小安装centos7,发现在使用命令安装图形界面的时候,尝试了 ...

  3. kafka C客户端librdkafka producer源码分析

    from:http://www.cnblogs.com/xhcqwl/p/3905412.html kafka C客户端librdkafka producer源码分析 简介 kafka网站上提供了C语 ...

  4. motto2

    Baby you've done enough that cut your breath.Don't beat yourself up don't need to turn so fast.Somet ...

  5. 利用Node.js对某智能家居服务器重构

    原文摘自我的前端博客,欢迎大家来访问 http://www.hacke2.cn 之前负责过一个智能家居项目的开发,外包重庆一家公司的,我们主要开发服务器监控和集群版管理. 移动端和机顶盒的远程通信是用 ...

  6. [译]我是怎么构建Node.js程序的

    原文: http://blog.ragingflame.co.za/2015/4/1/how-i-build-nodejs-applications "保持简单, 保持模块化." ...

  7. ROS之VPN服务器设置教程.

    关于ROS系统的安装此处将不再累述,可以自行谷歌,百度搜索“ROS 安装配置教程”. (安装方法可以使用光盘安装,USB引导安装,硬盘写入.) 好了,演示创建VPN服务器的方法: 1.使用WinBox ...

  8. 如何催促Apple进行App审核

    为什么提交给 App Store 的应用进入"审核(In Review)"状态后, 仍然可能会等待好多天的时间 ? 不过你也可以通过催促Apple进行App审核来缩短这个时间.以下 ...

  9. 【转】(笔记)CANopen协议【CANFestival】移植方法

    一.背景 CAN组网就必须得要应用层协议,原因就在于 * 便于网络管理与控制 * 确认数据的收发 * 发送大于8个字节的数据块(CAN每帧数据传输大小为8字节) * 为不同节点分配不同的报文标识符 * ...

  10. Ubuntu编译PHP7问题

    安装编译依赖 sudo apt-get -y install build-essential git autoconf sudo apt-get build-dep php5 sudo apt-get ...