《Effective Objective-C》阅读笔记(中)

目录

接口与API设计

用前缀避免命名空间冲突

提供“全能初始化方法”

实现description方法

尽量使用不可变对象

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

方法命名

​编辑类与协议命名

为私有方法名加前缀

理解OC错误模型

理解NSCopying协议

协议与分类

通过委托与数据源协议进行对象间通信

将类的实现代码分散到便于管理的数个分类之中

总是为第三方类的分类名称加前缀

​使用"class-continuation分类"隐藏实现细节

通过协议提供匿名对象


接口与API设计

用前缀避免命名空间冲突

为了避免“重名符号错误”,应当为所有名称都加上适当前缀,可以与公司、程序或二者皆有关。

但使用Cocoa创建程序时,要注意Apple保留使用所有“两字母前缀”的权利,所以开发者使用的前缀应该是三个字母的

不仅是类,还有C函数的名字也应加上前缀

如果是开发第三方库,那么对于所有包含的第三方库代码都加上自己的前缀。

提供“全能初始化方法”

可以为对象提供必要信息以便其能完成工作的初始化方法叫做“全能初始化方法”。

在上图方法中,initWithTimeIntervalSinceReferenceDate:便是全能初始化方法。

当一个类有多个初始化方法时,仍要选定一个作为全能初始化方法,其他初始化方法都调用它。

只有在全能初始化方法中,才会存储内部数据,这样的话,当底层数据存储机制改变时,只需修改此方法的代码就好。

如果子类的全能初始化方法与超类方法的名称不同,那么总应覆写超类的全能初始化方法。

实现description方法

在自定义类中,description的默认实现是打印类名和地址,输出信息如下:

这时我们应尽量将输出信息改为一个有意义的字符串,用来描述这个实例。有个简单的方法,就是借助NSDictionary的description方法。此方法输出的信息的格式如下:

字符串可以采用如下格式:

若想在调试时打印更详尽的描述信息,应实现debugDescripption方法。

尽量使用不可变对象

在编程实践中,应该尽量把对外公布出来的属性设为只读,而只在确有必要时才将属性对外公布。

有时可能想修改封装在对象内部的数据,但是不想让这些数据为外人所改动,这种情况下通常做法是将readonly重新声明为readwrite,这一操作应该在"class-continuation分类"中完成。

在定义类的公共API时,还应注意:对象里表示各种collection的那些属性应该设成可变的,还是不可变的。

比如:我们用某个类来表示个人信息,该类中还存放了一些引用指向此人的朋友,开发者可以添加或删除朋友,那这个属性就要用可变的set来实现。这种情况下,通常应该提供一个readonly属性供外界使用,返回一个不可变的set,这个set是内部可变set的一份拷贝。比如下面这份代码:

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

OC当中方法与变量名采用“驼峰式大小写命名法”,而类名首字母大写,并且有两三个前缀字母。

方法命名

命名方法时,应当使方法像个日常用语中的句子,准确传达方法所执行的任务,然而方法名不能长得太过分,应尽量言简意赅。

类与协议命名

类与协议的名称应加上前缀,并且应该像给方法起名一样组织好词句,使从左至右比较通顺。

为私有方法名加前缀

在编写私有方法时,最好使用前缀将私有方法标注出来,前缀最好包含下划线与字母p。

要注意不应该直接使用下划线作为私有方法的前缀,因为苹果公司喜欢单用一个下划线作为私有方法的前缀,使用一个下划线有可能会无意中覆写超类中的其他方法。

理解OC错误模型

自动引用计数不是“异常安全”的,并且即使不用ARC,也很难写出在抛出异常时不会导致内存泄漏的代码。所以OC语言当中,异常只用于极其严重的错误,抛出异常之后,应用程序应该退出,也就无需考虑恢复问题了

在出现不那么严重的错误时,OC语言所用的编程范式为:令方法返回nil/0,或是使用NSError,以表明其中有错误发生。

NSError的用法更加灵活,NSError对象里封装了三条信息:

Error domain:错误发生的范围,也就是产生错误的根源。

Error code:独有的错误代码,用以指明在某个范围内具体发生了何种错误。

User info:有关此错误的额外信息。

NSError有两种常见用法,一种是通过委托协议来传递错误,另一种是经由方法的“输出参数”返回给调用者。

理解NSCopying协议

OC中如果想令自己的类支持拷贝操作,那就要实现NSCopying协议,该协议只有一个方法:

这里zone参数不用考虑,使用默认参数即可。比如游客表示个人信息的类,可以声明遵从NSCopying协议:

有时需要获取可变的拷贝,则应遵守NSMutableCopying协议,该协议也只定义了一个方法:

当对象需要深拷贝时,可考虑吧新增一个专门执行深拷贝的方法

协议与分类

通过委托与数据源协议进行对象间通信

OC开发中经常使用一种“委托模式”,主旨是:定义一套接口,某对象若想接受另一个对象的委托,则需遵从此接口,以成为其“委托对象”,而这另一个对象,则可以给其委托对象回传一些信息,也可以在发生相关事件时通知委托对象。一般通过协议来实现委托模式。

用一张图来演示委托模式的概念:

这里EOCDataModel1就是作为EOCNetwirkFetcher的委托对象。

但是要注意,类中存放委托对象的属性需定义成weak,而非strong:

@interface EOCNetworkFetcher : NSObject
@property (nonatomic, weak) id <EOCNetworkFetcherDelegate> delegate;
@end

因为通常delegate要持有本对象,若本对象也持有delegate,那么就会引入保留环。

实现委托对象可以在接口中声明,也可以在“class-continuation分类”中声明。如果要向外界公布此类实现了某协议,那么就在接口中声明,如果是委托协议,通常只在类内部使用,一般在"class-continuation分类"里声明。

还有另一种,令某类经由协议中接口获取所需的数据,被称为“数据源模式”。

若有必要,可实现含有位段的结构体,将委托对象是否能相应相关协议方法这一信息缓存至其中。

将类的实现代码分散到便于管理的数个分类之中

当类中存在大量方法的代码时,可以通过OC的分类机制,把类代码按逻辑划入几个分区中。

比如下面这个管理个人信息的类:

可以把不同的方法放入不同分类中:

这些分类可以全部放在一个实现文件中,但当存在许多分类时,最好每个分类提取到各自的文件中去。以EOCPerson为例,可以拆分成下列这几个文件:

私有方法应归入名叫Private的分类中,以隐藏实现细节。

总是为第三方类的分类名称加前缀

我们经常通过分类为无源码的既有类添加方法,这时就容易出现命名冲突的问题。我们应该为分类和方法添加了前缀。

比如为NSString添加分类处理HTTP URL有关的字符串。

我们为其加上前缀:

使用"class-continuation分类"隐藏实现细节

class-continuation分类"和普通的分类不同,他必须定义在其所接续的那个类的实现文件里,这是唯一能声明实例变量的分类。

这种分类在实现文件中格式如下:

通过这种分类可以获得隐藏程度更好的私有方法和私有变量。

除了获得隐藏变量和方法之外,使用这种分类还可以将只读的属性扩展为可读写的,以便在类的内部设置其值。

还有一种用法是,当对象所遵从的协议只应视为私有,则可在该分类中声明

通过协议提供匿名对象

有时,我们可以把返回的对象设计为遵从某协议的id类型,这样的话,想要隐藏的类名就不会出现在API之中了。若接口背后有多个不同的实现类,又不想指明具体使用哪个,可以考虑用这个方法,此概念被称为“匿名对象”。

有时对象类型不重要,重要的是有没有实现某些方法,在此情况下,也可以使用这些“匿名类型”来表达这一概念。

比如对受委托者的定义:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB—(一主、一从、一仲裁)副本集搭建

MongoDB集群介绍&#xff1a; MongoDB 副本集是由多个MongoDB实例组成的集群&#xff0c;其中包含一个主节点&#xff08;Primary&#xff09;和多个从节点&#xff08;Secondary&#xff09;&#xff0c;用于提供数据冗余和高可用性。以下是搭建 MongoDB 副本集的详细步骤&am…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.3.1单节点安装(Docker与手动部署)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 10分钟快速部署Elasticsearch单节点环境1. 系统环境要求1.1 硬件配置推荐1.2 软件依赖 2. Docker部署方案2.1 部署流程2.2 参数说明2.3 性能优化建议 3. 手动部署方案3.1 安…

Rt-thread源码剖析(1)——内核对象

前言 该系列基于rtthread-nano的内核源码&#xff0c;来研究RTOS的底层逻辑&#xff0c;本文介绍RTT的内核对象&#xff0c;对于其他RTOS来说也可供参考&#xff0c;万变不离其宗&#xff0c;大家都是互相借鉴&#xff0c;实现不会差太多。 内核对象容器 首先要明确的一点是什…

html css js网页制作成品——HTML+CSS甜品店网页设计(5页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

Trae根据原型设计稿生成微信小程序密码输入框的踩坑记录

一、需求描述 最近经常使用Trae生成一些小组件和功能代码&#xff08;对Trae赶兴趣的可以看之前的文章《TraeAi上手体验》&#xff09;&#xff0c;刚好在用uniapp开发微信小程序时需要开发一个输入密码的弹框组件&#xff0c;于是想用Trae来实现。原型设计稿如下&#xff1a;…

斩波放大器

目录 简介 自稳零斩波放大器 噪声 简介 双极性放大器的失调电压为25 μV&#xff0c;漂移为0.1 μV/C。斩波放大器尽管存在一些不利影 响&#xff0c;但可提供低于5 μV的失调电压&#xff0c;而且不会出现明显的失调漂移&#xff0c; 以下图1给出了基本的斩波放大器电路图。…

windows设置暂停更新时长

windows设置暂停更新时长 win11与win10修改注册表操作一致 &#xff0c;系统界面不同 1.打开注册表 2.在以下路径 \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键新建 DWORD 32位值&#xff0c;名称为FlightSettingsMaxPauseDays 根据需求填写数…

DIALOGPT:大规模生成式预训练用于对话响应生成

摘要 我们提出了一个大规模、可调节的神经对话响应生成模型&#xff0c;DIALOGPT&#xff08;对话生成预训练变换器&#xff09;。该模型训练于从2005年至2017年间Reddit评论链中提取的1.47亿次类似对话的交流&#xff0c;DIALOGPT扩展了Hugging Face的PyTorch变换器&#xff…

Mac端不显示正常用户名,变成192的解决方法

今天打开终端&#xff0c;本应该显示机器名的&#xff0c;但是此时显示了192。 问题原因&#xff1a; 当路由器的DNS使用默认的 192.168.1.1 或 192.168.0.1 的时候 Terminal 里的计算机名 会变成 localhost。当路由器的DNS使用自定义的 例如 运营商的DNS 或者 公共DNS的时候 …

SD 卡无屏安装启动树莓派5

最近想用一下树莓派5&#xff0c;拿出来一看&#xff0c;是 Micro-HMDI 的接口&#xff0c;手头正好没有这个接口线&#xff0c;便研究如何在没有显示屏的情况下&#xff0c;安装启动树莓派。 一、使用 Raspberry Pi Imager 烧录 SD 卡 选择 Raspberry Pi Imager 来烧录 SD 卡…

Xlua 编译 Windows、UWP、Android、iOS 平台支持库

Xlua 编译 Windows、UWP、Android、iOS 平台支持库 Windows&#xff1a; 安装 Visual Studio&#xff08;推荐 2017 或更高版本&#xff09; 安装 CMake&#xff08;https://cmake.org/&#xff09; macOS&#xff1a; 安装 Xcode 和命令行工具 安装 CMake 检查 cmake 是否安…

npm : 无法加载文件 E:\ProgramFiles\Nodejs\npm.ps1,因为在此系统上禁止运行脚本。

这个错误是因为 Windows 系统的 PowerShell 执行策略 限制了脚本的运行。默认情况下&#xff0c;PowerShell 的执行策略是 Restricted&#xff0c;即禁止运行任何脚本。以下是解决该问题的步骤&#xff1a; 1. 检查当前执行策略 打开 PowerShell&#xff08;管理员权限&#x…

基于专利合作地址匹配的数据构建区域协同矩阵

文章目录 地区地址提取完成的处理代码 在专利合作申请表中&#xff0c;有多家公司合作申请。在专利权人地址中&#xff0c; 有多个公司的地址信息。故想利用这里多个地址。想用这里的地址来代表区域之间的专利合作情况代表区域之间的协同、协作情况。 下图是专利合作表的一部分…

若依vue plus环境搭建

继前面文章若依系统环境搭建记录-CSDN博客 把ruoyi vue plus也摸索了下。 作者是疯狂的狮子&#xff0c;dromara/RuoYi-Vue-Plus 初始化文档&#xff1a;项目初始化&#xff0c;环境搭建的视频&#xff1a;RuoYi-Vue-Plus 5.0 搭建与运行_哔哩哔哩_bilibili 上来就列出了一…

在ubuntu如何安装samba软件?

我们在开发过程中&#xff0c;经常修改代码&#xff0c;可以安装samba文件来实现&#xff0c;把ubuntu的存储空间指定为我们win上的一个磁盘&#xff0c;然后我们在或者磁盘里面创建.c文件&#xff0c;进行代码修改和编写。samba能将linux的文件目录直接映射到windows&#xff…

论文阅读笔记:Deep Face Recognition: A Survey

论文阅读笔记&#xff1a;Deep Face Recognition: A Survey 1 介绍2 总览2.1 人脸识别组件2.1.1 人脸处理2.1.2 深度特征提取2.1.3 基于深度特征的人脸对比 3 网络结构和损失函数3.1 判别损失函数的演化3.1.1 基于欧式距离的损失3.1.2 基于角度/余弦边距的损失3.1.3 Softmax损失…

使用 Polars 进行人工智能医疗数据分析(ICU数据基本测试篇)

引言 在医疗领域&#xff0c;数据就是生命的密码&#xff0c;每一个数据点都可能蕴含着拯救生命的关键信息。特别是在 ICU 这样的重症监护场景中&#xff0c;医生需要实时、准确地了解患者的病情变化&#xff0c;以便做出及时有效的治疗决策。而随着医疗技术的飞速发展&#x…

Fiddler在Windows下抓包Https

文章目录 1.Fiddler Classic 配置2.配置浏览器代理自动代理手动配置浏览器代理 3.抓取移动端 HTTPS 流量&#xff08;可选&#xff09;解决抓取 HTTPS 失败问题1.Fiddler证书过期了 默认情况下&#xff0c;Fiddler 无法直接解密 HTTPS 流量。需要开启 HTTPS 解密&#xff1a; 1…

Anaconda安装 超详细版 (2025版)

目录 第一步&#xff1a;下载anaconda安装包 官网下载&#xff1a;Anaconda | Built to Advance Open Source AI 清华大学镜像站下载&#xff08;速度较快&#xff09; 第二步&#xff1a;安装anaconda 第三步&#xff1a;验证安装 扩展 创建conda基本环境 激活conda环…

想知道两轮差速方形底盘 URDF 咋做,ROS2 配 Rviz 咋显示吗?看这里!

视频讲解 想知道两轮差速方形底盘 URDF 咋做&#xff0c;ROS2 配 Rviz 咋显示吗&#xff1f;看这里&#xff01; 模型概述 一个方形底盘和两个差速驱动轮 URDF 代码 <?xml version"1.0" encoding"utf-8"?> <robot name"diff"> …