【Effective_Objective-C_3接口与API设计】

news2024/11/20 23:30:11

文章目录

  • 前言
  • 15.用前缀避免命名空间冲突
    • 要点总结
  • 16.提供全能初始化方法
        • 全能初始化
        • 要点
  • 17.实现description方法
        • description
        • 以字典形式输出description
        • debugDescription
    • 要点
  • 18.尽量使用不可变对象
    • 要点
  • 19.使用清晰协调的命名方式
        • 方法命名
        • 类与协议命名
    • 要点
  • 20.为私有方法名加前缀
  • 21.理解Objective-C的错误类型
        • ARC的异常安全
        • NSError
            • NSError用法
    • 要点
  • 22.理解NSCopying协议
        • NSCopying
        • 深浅拷贝的使用时机
    • 要点
  • 总结

前言

  • 继续学习Effective_Objective-C。这一章的简介就是在于让开发者熟练的掌握OC语言的编程规范。

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

  • OC语言中没有其他语言那种内置的命名空间机制,所以我们在对文件命名时要十分的注意,若是发生重名冲突,那么应用程序相应的链接过程就会出错,导致运行文件不知道究竟该调用那个文件,因为其中出现了重复的符号。
  • 也就是理解成命名的时候需要加上前缀,比如一个项目里存在很多歌ViewController的子类,那么在命名的时候需要分清楚子类的名称,加上前缀总是好的请添加图片描述

要点总结

  • 选择与你的公司、应用程序或者二者皆有关联的名称作为类名的前缀,并在所有代码中均使用这一前缀。
  • 若是自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀。

16.提供全能初始化方法

  • OC里的所有对象都要经过初始化的过程,有时候有些对象无需开发者向其提供额外信息就能完成初始化✅,但是有时候系统必须为对象提供必要的信息帮助其完成初始化的方法叫做“全能初始化”。

全能初始化

  • 如果创建类实例的方式不止一种,那么这个类就会有许多个初始化方法。在这个过程里有一个方法使得其他方法初始化的时候必须调用它,那么这个方法称“全能初始化方法”。
  • 只有在全能初始化方法中,才会存储内部数据,其他的方法只是在存储内部数据后再进行了一些其他操作而已

要点

  • 在类中提供一个全能初始化方法,并与文档里指明。其他初始化方法均应调用此方法。
  • 若全能初始化方法与超类不同,则需覆写超类中的对应方法。
  • 如果超类的初始化方法不适用于子类,那么应该覆写这个超类方法,并在其中抛出异常。
  • 一个类有多个全能初始化方法要注意,我们就是要维持原来类的调用链,每个子类的全能初始化方法都应该调用其超类的对应方法,并逐层向上。因为其父类有两个全能初始化方法,这两种初始化方法定义出来的数据可能是不同的,若是你在子类中调用了错误的父类初始化方法,它就会可能因为数据类型的问题使程序发生错误
  • 重写初始化方法也要注意如果子类的全能初始化方法与超类方法的名称不同,我们总应覆写超类的全能初始化方法,避免子类调用父类的全能初始化方法

17.实现description方法

  • 这一条的主要意思就是在调试的过程里面,我们通常会选择打印在控制台或者打断点,这里对这两种调试方法进行了详细说明和建议!

description

  • 调试程序的时候,打印数组信息并查看信息如下
    请添加图片描述
  • 在构建需要打印到日志的字符串的时候,array对象会收到来自descriprion的消息,该方法返回得到描述信息将取代“格式字符串的%@”。
  • 如果自定义类呢?我尝试打印了一下button类。
    请添加图片描述
  • 接着自定义类
    请添加图片描述
  • 和button的信息相比较,上面的内容不太有用,这里就提到了可以在自己的类覆写description方法,否则打印的时候就会调用NSObject的默认方法。
    请添加图片描述
  • EOCPerson里有自己的名字,我们在m文件重写description打印自己需要的。这也是吗了UIButton里面的实现也是改变了,它选择打印了自己的frame layer等属性请添加图片描述

#import "EOCPerson.h"
@interface EOCPerson : NSObject
@property (nonatomic, strong)NSString *firstName;
@end

@implementation EOCPerson
- (NSString *)description {
    return [NSString stringWithFormat:@"< %p, \"%@>",self, self.firstName];
}
@end

请添加图片描述

以字典形式输出description

  • 书上还介绍了以字典形式输出description,原理都是一样的,只是实现的时候多加了一步,那样看起来更加方便

debugDescription

  • 在NSObject协议里面还有一个方法也是用来调试打印代码 debugDescription
  • 二者区别在于就是描述的位置不一样,description是在函数调用类的时候触发方法才输出的,而debugDescription是在控制台中使用命令打印该对象时才调用的。当然加断点查看时也可以看到debugDescription的描述
  • 这里还交给我们了一个调试方法是 po + 类可以打印详细的信息请添加图片描述
  • 如果你在description不想将一些内容输出的话,你就可以将那些数据写在debugDescription中,让程序员自己调试时可以方便的看到这些数据,而description方法就输出你想要让用户看到的信息就行了。

要点

  • 实现description方法返回一个有意义的字符串,用以描述该实例。
  • 若想在调试时打印出更详尽的对象描述信息,则应实现debugDescription方法。

18.尽量使用不可变对象

  • 这里的不可变对象不是使用系统提供的不可变类,而是在设置属性的时候添加上readnoly属性
  • 默认情况下的属性是既可读又可写的,这样的类我们在这里成为可变类,但一般的数据未必需要改变。
  • 原则上尽量把对外公布出来的属性设为只读,并且在有确定的必要的时候设为可读。
    请添加图片描述
  • 当我们需要修改封装在对象内部的数据的的时候而且不想数据被外人改动的时候,需要将readonly改为readwrite并且为了避免竞争条件的出现,我们可在必要的时候通过派发队列等手段将数据的存储设置为同步操作(暂时未了解)
    请添加图片描述
  • 虽然保持了只能在代码内部实现属性,但其实还可以通过KVC来设置属性。

要点

  • 尽量创建不可变的对象。
  • 若某属性仅可于对象内部修改,则在“class-continuation分类”中将其由readonly属性扩展为readwrite属性。
  • 不要把可变的collection作为属性公开,而应提供相关方法,以此修改对象中的可变collection。

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

  • 清晰的命名读起来是很方便的,这个习惯需要及时的纠正,不仅自己可以读懂,其他人也可以读懂,在合作的时候显得颇为重要

方法命名

  • 如果方法的返口值是新创建的,那么方法名的首个词应是返回值的类型,除非前面还有修饰语,例如localizedString。属性的存取方法不遵循这种命名方式,因为一般认为这些方法不会创建新对象,即便有时返口内部对象的一份拷贝,我们也认为那相当手原有的对象。这些存取方法应该按照其所对应的属性来命名。
  • 应该把表示参数类型的名词放在参数前面。
  • 如果方法要在当前对象上执行操作,那么就应该包含动词;若执行操作时还需数,
    则应该在动词后面加上一个或者多名词
  • 不要使str这种简称,应该用 string 这样的全称。(经典)
  • Boolean 属性应加is前级。如果某方法返口非属性的 Boolean 值,那么应该根据其功
    能,选用has 或is 当前缀。
  • get这个前缀留给那些借由“输出” 参数,来保布返口值的方法,比如说,把返回值填充到“C语言式数组”(C-style array)里的那种方法就可以使用这个词做前缀。

类与协议命名

  • 应该为类与协议的名称加上前缀,以避免命名空间冲突,而且应该像给方法起名时那样把词句组织好,使其从左至右读起来较为通顺。基本命名规则就是:命名方式应该一致,如果要从其他的类中继承子类,那么就要遵守其原本的命名惯例。 例如:UIView它的子类就应该是***View,表明其来历。
  • 在写自己项目的时候就出现了这个问题,我把view放在前面了导致看的时候比较混乱,一大段的view 不知道哪个是哪个

要点

  • 起名时应遵从标准的OC命名规范,这样创建出来的接口更容易为开发者所理解。
  • 方法名要言简意赅,从左至右读起来要像个日常用语中的句子才好。
  • 方法名里不要使用缩略后的类型名称。
  • 方法名起名时的第一要务就是确保其风格与你自己的代码或所要集成的框架相符。

20.为私有方法名加前缀

  • 通常我们在写方法时,并没有对其进行私有共有分类,导致调试时可能很麻烦,现在为私有方法加上前缀,这样便于修改方法或方法签名。具体加什么来代表私有方法因人而异,自己怎么舒服怎么来,唯一注意的是:一定不要只使用_作为前缀,用p_都比那个好,因为苹果公司使用的就是_作为私有方法的前缀的,你自己定义的私有方法名有可能就会和人家自带的冲突。
  • 给私有方法的名称加上前缀,这样可以很容易地将其同公共方法区分开。
  • 不要单用一个下划线做私有方法的前缀,因为这种做法是预留给苹果公司用的。

21.理解Objective-C的错误类型

  • 对于现在的Objective-C来说只有发生了可使整个应用程序崩溃的严重错误时,才应使用异常,但是在之前代码抛出异常的时候是存在很多。

ARC的异常安全

  • ARC的异常机制举例“自动引用计数”在默认情况下不是“异常安全的”,就是说,如果抛出异常,那么本应该在作用域末尾释放的对象现在却不会释放了,这样就会造成内存泄漏问题,如果想生成“异常安全”的代码,可以通过设置编译器的标志来实现,不过这将引入一些额外的代码,在不抛出异常时,也照样要执行这部分代码。需要打开的编译器标志叫做-fobjc-arc-exceptions
    • 对于-fobjc-arc-exceptions我稍稍了解了一下
      • 在ARC中异常可能会导致对象的内存泄露。因为ARC是颗粒化对象为一个文件:即可以在obj-c文件上启用ARC.所以我们可以选择性的在编译某个文件上加上-fobjc-arc-exceptions选项 如果开启了该选项,则ARC会额外为异常中的对象申请和释放操作添加代码,保证异常中ARC管理的对象也不会造成内存泄露。当然这样一来缺点就是可能会生成大量平常可能根本用不到的代码。(只有发生异常才会执行) 还需要注意的是我们可以只在必要的obj-c文件上启用-fobjc-arc-exceptions标志,而其他文件禁用该标志,这样才可以做到不浪费多余的内存和空间
  • 所以OC语言现在的解决方法就是只在及其罕见的情况下抛出异常,异常抛出之后,无须考虑恢复问题,而且这时应用程序也应该退出了,所以无需我们去写“异常安全代码”了。

NSError

  • 现在OC不会轻易的抛出异常,当然错误是随时都可能发生的,所以对于没有达到严重错误级别的错误,OC语言会返回nil 或者 0,还有就是使用NSError.以表明其中有错误发生.
  • 这个是返回nil的例
    请添加图片描述
    • 在这周情况下,如果发现无法创建self,则self置nil,我们创建的时候发现创建不出来对象就会知道出错了
  • NSError相比之下更加的灵活,它可以把错误的原因回报给调用者。封装如下
    请添加图片描述
NSError用法
  • 第一种常见就是通过委托协议传递这个错误,当前对象会把协议中的某个方法传给委托的对象,此方法常用于API的设计。
    请添加图片描述
  • 另一种常见用法是:经由方法的“输出参数”返回给调用者。就是说用一个方法来判断你传过去的error是否真的有错误,返回Boolean值,之后你就可以根据error是否有内容,或者Boolean值来决定处理的代码和不处理的代码
    请添加图片描述
  • 还可以为error参数“解引用(error所指的那个指针现在要指向一个新的NSError对象)”之前,必须先保证error参数不是nil,因为空指针解引用会导致段错误并使程序崩溃,所以注意要判断error是不是nil。
  • 错误范围和错误码和用户信息等分别返回不同的类型:
    • 调用者就可以根据错误的类型分别处理各种错误了。错误范围应该定义成NSString型的全局变量,而书上推荐错误码则定义成枚举类型为佳。
      请添加图片描述

要点

  • 只有发生了可使整个应用程序崩溃的严重错误时,才应使用异常。
  • 在错误不那么严重的情况下,可以指派“委托方法”来处理错误,也可以把错误信息放在NSError对象里,经由“输出参数”返回给调用者。
    • NSError 对象里封装了三条信息:
      • Error domain(错误范围,其类型为字符串)
      • Error code(错误码,其类型为整数)
      • User info(用户信息,其类型为字典)

22.理解NSCopying协议

  • 又遇到了Copy…
  • 使用对象的时候经常觉得是否进行拷贝,深拷贝还是浅拷贝?对于这些问题在OC语言里面需要通过copy方法完成。
  • 对于系统自带的容器类,字典数组集合都自带copy方法,这里需要说的是我们需要对自己自定义的类实现copy的时候,如何实现?

NSCopying

  • NSCopying是NSObject的协议之一,它用于实现自定义类的copy。
  • 该协议只有一个方法请添加图片描述
    • NSZone: 在之前开发程序的时候会吧内存分成不同的区,对象则会被创建在某个区里面,现在所有的程序只有一个“默认区”,所以无需紧要这个区
  • 若想某个类实现copy功能,则需要声明NSCopying协议然后实现对应的方法。
  • 需要注意如果你的类分为可变版本和不可变版本那么还需要实现NSMutableCopying协议和对应的方法
@protocol NSCopying

- (id)copyWithZone:(nullable NSZone *)zone;

@end

@protocol NSMutableCopying

- (id)mutableCopyWithZone:(nullable NSZone *)zone;

@end

请添加图片描述

  • 对于不可变的NSArray与可变的NSMutableArray来说,存在如下关系
[NSMutableArray copy] => NSArray
[NSArray mutableCopy] => NSMutableArray

    • 在可变的对象实现不可变copy返回的是另外一个不可变实例,如此做是为了能在可变版本和不可变版本实现自由切换

深浅拷贝的使用时机

  • 要执行“深拷贝”还是“浅拷贝”?
    • 深拷贝:在拷贝对象自身时,将其底层数据也一并复制过去。
    • 浅拷贝:在拷贝对象自身时,只拷贝容器对象本身,而不复制其中的数据。
      请添加图片描述
  • 如果有需要,我们可以自行添加一个深拷贝方法。请添加图片描述
  • 这个自行实现的深拷贝也可以看出来深浅拷贝的区别,深拷贝是在堆里新开辟一块内存存放底层数据。
  • 浅拷贝是只拷贝存放在栈上指向堆内存的指针。
	NSArray *array = @[@"immutableCopy", @"mutableCopy"];
    NSArray *immurtableArray = [array copy];
    NSArray *mutableArray = [array mutableCopy];

请添加图片描述
请添加图片描述
请添加图片描述

    • 可以看出copy出的immuatleArray和原array指向了同一块内存区。而mutalbeArray在堆里新开辟一块内存存

要点

  • 若想令自己所写的对象具有拷贝功能,则需实现NSCopying协议。
  • 如果自定义的对象分为可变版本和不可变版本,那么就要同时实现NSCopying与NSMutableCopying协议。
  • 复制对象时需决定采用浅拷贝还是深拷贝,一般情况下应该尽量执行浅拷贝。
  • 如果你所写的对象需要深拷贝,那么可考虑新增一个专门执行深拷贝的方法。

总结

  • 这一章学的大部分之前都了解过或者使用过但不知道原理,还是要加深印象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/111952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人-机器人交互导论

【编者按&#xff1a;变主体性才是智能的真正厉害之处&#xff0c;能够设身处地地转换角色、角度、视角看待交互对象中的不确定性&#xff0c;并使用相应的同理同情共主观性机制机理进行处理&#xff0c;例如梅西过人中的真假变化。在个体/群体智能中的变主体性控制也是人机环境…

【圣诞节】飘雪圣诞树

一、前言 马上2023年的圣诞节&#x1f384;要到了&#xff0c;作为一个程序员&#xff0c;没什么可以送给大家的&#xff0c;就给大家画一个圣诞树&#x1f384;&#xff0c;作为礼物来送给大家吧。 二、创意名 明月当空飘雪圣诞树 三、效果展示 四、实现步骤 主要是利用three.…

详细设计说明书(GB8567——88)基于协同的在线表格forture-sheet

详细设计说明书 1引言 1.1编写目的 该文档在概要设计的基础上&#xff0c;进一步的细化系统结构&#xff0c;展示了软件结构的图标&#xff0c;物理设计、数据结构设计、及算法设计、详细的介绍了系统各个模块是如何实现的&#xff0c;包括涉及到的算法&#xff0c;逻辑流程…

【LeetCode每日一题:1754. 构造字典序最大的合并字符串~~~双指针+贪心算法】

题目描述 给你两个字符串 word1 和 word2 。你需要按下述方式构造一个新字符串 merge &#xff1a;如果 word1 或 word2 非空&#xff0c;选择 下面选项之一 继续操作&#xff1a; 如果 word1 非空&#xff0c;将 word1 中的第一个字符附加到 merge 的末尾&#xff0c;并将其…

《Unified Structure Generation for Universal Information Extraction》论文阅读

文章目录文章介绍文章方案用于统一结构编码的结构化抽取语言&#xff08;SEL&#xff09;用于可控IE结构生成的结构模式指导使用UIE生成预训练任务微调任务总结参考文章地址&#xff1a; https://arxiv.org/abs/2203.12277文章介绍 目前对于自然语言处理中的信息抽取任务如关系…

业聚医疗港交所上市:市值76亿港元 为钱永勋家族企业

雷递网 雷建平 12月23日血管介入器械公司――业聚医疗集团有限公司&#xff08;OrbusNeich Medical Group Limited&#xff09;&#xff08;简称“业聚医疗”&#xff0c;股票代码为&#xff1a;6929 &#xff09;今日在港交所上市。业聚医疗发行价为8.8港元&#xff0c;募资净…

SpringCloudGateway源码(四)限流组件

前言 如果不使用Alibaba Sentinel的网关流控规则&#xff0c; 是否可以选择使用SpringCloudGateway基于Redis的限流组件&#xff1f; 基于这个问题&#xff0c;笔者想了解一下scg自带限流组件的实现原理。 一、使用案例 1、pom 注意要加入redis-reactive依赖。 <depe…

OA系统遇到的问题

目录 一、开始时间与结束时间之差 二、弹出层的大小以及位置设置 2.1、高度设置body-style 2.2、位置设置dialogStyle 三、vue2安装引入Ant Design Vue 四、按钮控制盒子的显示与隐藏 五、表单生成器思想 5.1、点击左侧控件库生成中间的控件元素 5.2、点击中间的控件&…

Flink-状态编程的基本概念

文章目录Flink 中的状态1.1 有状态算子1.2 状态的管理1.3 状态的分类&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e; 更多资源链接&#xff0c;欢迎访问作者gitee仓库&#xff1a;https://gitee.com/fanggaolei/learning-notes-warehouse/tree/master Fli…

springcloud-gateway简介

目录 1. gateway简介 1.1 是什么 1.2 作用 1.3 主要特征 1.4 与zuul的主要区别 1.5 主要组件 1.6 架构图 2. 开发示例 2.1 创建一个gateway模块 2.2 与nacos结合使用 2.2.1 默认规则 2.2.2 通过配置文件配置路由 2.2.3 动态路由 1. gateway简介 1.1 是什么 SpringC…

一文带你深入理解【Java基础】· 网络编程(上)

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Kali Linux中安装IDLE的方法

1 IDLE简介 IDLE是Integrated Development and Learning Enviroment即集成开发和学习环境的简称&#xff0c;是Python的集成开发环境。在Kali Linux中&#xff0c;可以通过IDLE进行Python编程。 2 Kali Linux中安装IDLE 2.1 查看Kali Linux中是否安装IDLE 在Kali Linux终端…

WEB1.0起源:全球首个网站info.cern.ch

伯纳斯李&#xff08;图&#xff09;1990年创立第一个网站。 info.cern.ch是世上第一个网站&#xff0c;提供有关万维网的资料。 info.cern.ch这个网站依然运作如常。 英国科学家蒂姆伯纳斯-李 (Tim Berners-Lee) 于 1989 年在 CERN 工作期间发明了万维网 (WWW)。Web 最初的构思…

基于Vue+SpringBoot智慧校园疫情防控系统(PC端、手机端)--附源码

介绍 智慧校园疫情防控系统——PC 手机端 多端并行 项目源码下载&#xff1a;https://download.csdn.net/download/DeepLearning_/87340321 软件架构 手机端信息系统——日常健康信息填报系统&#xff08;前端手机端 文件夹&#xff09;电脑端智疫图 —— 数据可视化界面 &…

一种新的语义分割思路

这两天看到一篇挺有意思的论文&#xff0c;虽然不是语义分割方面的但是挺有意思的&#xff0c;因此在这里跟大家分享一下&#xff0c;这个也是一种语义分割的思路和方法。 Paper&#xff1a;Fully-Convolutional Siamese Networks for Object Tracking. SiamFC是深度学习目标…

【深入浅出 Yarn 架构与实现】4-2 RM 管理 Application Master

上一篇文章对 ResourceManager 整体架构和功能进行了讲述。本篇将对 RM 中管理 Application Master 的部分进行深入的讲解。 下面将会介绍 RM 与 AM 整体通信执行流程&#xff0c;并对 RM 中涉及的对应服务进行具体讲解。 为了更好的学习本篇知识&#xff0c;建议先熟悉以下知识…

股票量化分析工具QTYX使用攻略——实盘交易信号监控(更新2.5.7)

搭建自己的量化系统如果要长期在市场中立于不败之地&#xff01;必须要形成一套自己的交易系统。如何学会搭建自己的量化交易系统&#xff1f;边学习边实战&#xff0c;在实战中学习才是最有效地方式。于是我们分享一个即可以用于学习&#xff0c;也可以用于实战炒股分析的量化…

3天学会撰写软件发明专利——5.专利法律常识

“无意中发现了一个巨牛的人工智能教程&#xff0c;忍不住分享一下给大家。教程不仅是零基础&#xff0c;通俗易懂&#xff0c;而且非常风趣幽默&#xff0c;像看小说一样&#xff01;觉得太牛了&#xff0c;所以分享给大家。点这里可以跳转到教程。”。 1)假冒专利行为及其法…

Activemq的Broker

目录 一、broker是什么 二、启动broker时指定配置文件 三、嵌入式Broker &#xff08;一&#xff09;Pom.xml &#xff08;二&#xff09;Broker实例 &#xff08;三&#xff09;验证 一、broker是什么 相当于一个ActiveMQ服务器实例。说白了&#xff0c;Broker其实就是…

YK-L1刷机

文章目录1.测试是否能够连接到路由器2.刷breed3.Padavan firmware编译4.烧板5.验证杂文1.1内核模块编写&#xff08;使用insmod方式&#xff09;1.2内核模块编写&#xff08;跟随内核一起编译&#xff09;参考资料1.测试是否能够连接到路由器 插上网线和电脑相连&#xff0c;网…