《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之中了。若接口背后有多个不同的实现类,又不想指明具体使用哪个,可以考虑用这个方法,此概念被称为“匿名对象”。
有时对象类型不重要,重要的是有没有实现某些方法,在此情况下,也可以使用这些“匿名类型”来表达这一概念。
比如对受委托者的定义:
相关文章:
《Effective Objective-C》阅读笔记(中)
目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…...
前端如何解决跨域
解决前端跨域问题有多种方法 JSONP:利用 <script> 标签的跨域能力,通过动态创建 script 标签并指定回调函数来获取数据。但只能处理 GET 请求,安全性较低。 JSONP 的原理是利用了 <script> 标签的跨域能力。因为浏览器允许 <…...
【HDLbits--Comb组合逻辑】
HDLbits--Comb组合逻辑 1.5 组合逻辑1.5 Demo 在 Verilog 中,组合逻辑(Combinational Logic)是指输出仅依赖于当前输入的逻辑电路,没有记忆功能(即没有状态存储)。组合逻辑的特点是: 无时钟信号…...
如何在 Linux 上安装和配置 Zsh
文章目录 如何在 Linux 上安装和配置 Zsh1. 安装 Zsh1.1 在 Ubuntu/Debian 上安装1.2 在 CentOS/RHEL/Fedora 上安装1.3 在 Arch Linux 上安装1.4 验证 Zsh 安装 2. 设置 Zsh 为默认 Shell2.1 验证默认 shell 3. 配置 Zsh3.1 使用 Oh My Zsh3.1.1 安装 Oh My Zsh3.1.2 启用插件…...
Chromedriver与Chrome版本映射表
Chromedriver与Chrome版本映射表如下: Chrome 71-73版本对应Chromedriver 2.46Chrome 70-72版本对应Chromedriver 2.45Chrome 69-71版本对应Chromedriver 2.44Chrome 68-70版本对应Chromedriver 2.43Chrome 67-69版本对应Chromedriver 2.42…...
HarmonyOS学习第7天: 文本组件点亮界面的文字魔法棒
一、引言 在 HarmonyOS 那丰富多彩的系统界面中,从简洁直观的应用图标,到交互流畅的操作菜单,再到生动形象的图文展示,每一处细节都经过精心雕琢,为用户带来了独特而美妙的视觉与交互体验。而在这琳琅满目的界面元素中…...
06C语言——指针
一、指针入门 (1)、准备知识 0、图解: 1、内存地址 字节:字节是内存的容量单位,英文称为 byte,一个字节有8位,即 1byte(0000 0000 --- 1111 1111) 8bits(0 --- 1) 地址:系统为了便于区分每一个字节而对…...
Ubuntu DeepSeek磁盘空间不够解决办法
标签: Ubuntu; DeepSeek磁盘空间不够解决办法;Ubuntu 22, DeepSeek R1 671 B, solution for Insufficient Disk Space 问题:Ubuntu 22, DeepSeek R1 671B 磁盘空间不够解决办法 Ubuntu 22.04操作系统,台式…...
东信营销科技巨额补贴仍由盈转亏:毛利率大幅下滑,现金流告急
《港湾商业观察》施子夫 近期,东信营销科技有限公司(以下简称,东信营销科技)递表港交所,联席保荐机构为海通国际和中银国际。 东信营销科技的国内运营主体为深圳市东信时代信息技术有限公司。尽管期内收入规模有所提…...
Qt layout
文章目录 Qt layout**关键机制****验证示例****常见误区****最佳实践****总结**关键点总结:示例代码说明:结论: Qt layout 在 Qt 中,当调用 widget->setLayout(layout) 时,layout 的父对象会被自动设置为该 widget…...
本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面
文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask,以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架,采用Python编程…...
基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
Android MMKV集成指南
首先简单介绍一下MMKV当下Android Studio最版本及Gradle8.7 MMKV集成根据官方文档重新对mmkv重新包了一次(便于开发)总结首先简单介绍一下MMKV MMKV 是腾讯开源的一款专为移动端设计的高性能键值存储组件,旨在替代传统的 SharedPreferences 和 SQLite,尤其在频繁读写和数据…...
React七Formik
Formik是一个专为React构建的开源表单库。它提供了一个易于使用的API来处理表单状态管理,表单验证以及表单提交。Formik支持React中的所有表单元素和事件,可以很好地与React生态系统中的其他库集成。同时,Formik还提供了一些高级功能…...
5分钟使用Docker部署Paint Board快速打造专属在线画板应用
文章目录 前言1.关于Paint Board2.本地部署paint-board3.使用Paint Board4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Paint Board公网地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住…...
可狱可囚的爬虫系列课程 14:10 秒钟编写一个 requests 爬虫
一、前言 当重复性的工作频繁发生时,各种奇奇怪怪提高效率的想法就开始萌芽了。当重复代码的模块化封装已经不能满足要求的时候,更高效的方式就被揭开了神秘的面纱。本文基于这样的想法,来和大家探讨如何 10 秒钟编写一个 requests 爬虫程序。…...
【深度学习神经网络学习笔记(三)】向量化编程
向量化编程 向量化编程前言1、向量化编程2、向量化优势3、正向传播和反向传播 向量化编程 前言 向量化编程是一种利用专门的指令集或并行算法来提高数据处理效率的技术,尤其在科学计算、数据分析和机器学习领域中非常常见。它允许通过一次操作处理整个数组或矩阵的…...
PHP入门基础学习四(PHP基本语法)
运算符 运算符,专门用于告诉程序执行特定运算或逻辑操作的符号。根据运算符的作用,可以将PHP语言中常见的运算符分为9类 算数运算符: 是用来处理加减乘除运算的符号 也是最简单和最常用的运算符号 赋值运算符 1. 是一个二元运算符&#x…...
【十二】Golang 映射
💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 映射映射的定义映射初始化make 函数使用字面量 源…...
简单理解Oracle中的latch
可以用一个小卖部抢购的例子来理解 Oracle 数据库中的 Latch: 1、 什么是 Latch? 打个比方,假设数据库的某个内存区域(比如缓存的数据块)是小卖部货架上的最后一包辣条,Latch 就像是货架前的一个狭窄通道&a…...
hbase集群部署
1.hbase集群的搭建(以及内部逻辑) 虽然Hmaster有多个,但是属于热备,起作用的就active上的这个。 部署流程: 因为我配置的hadoop是一个非HA的,所以修改为以下 如果是HA的hadoop一定要做以下这一步。 在启动…...
塔能物联运维保障智慧地下停车场安全与高效
一、智慧地下停车场安全在城市升级改造中的关键地位 随着城市的不断发展和升级改造,智慧地下停车场的重要性日益凸显。在现代城市中,土地资源愈发珍贵,地下停车场成为解决停车难题的关键设施。然而,停车场的安全问题是其正常运行和…...
面试八股文--数据库基础知识总结(2) MySQL
本文介绍关于MySQL的相关面试知识 一、关系型数据库 1、定义 关系型数据库(Relational Database)是一种基于关系模型的数据库管理系统(DBMS),它将数据存储在表格(表)中,并通过表格…...
深入理解指针2
深入理解指针2 数组名的理解 数组名就是首元素的地址 int arr[]{1,3,2}; printf("%p\n",arr); printf("%p\n",&arr[0]);但是有两种情况除外, 1.sizeof(数组名),sizeof操作符统计的是整个数组的大小,并不是第一个元素…...
QT各种版本下载安装
参考链接: 【Qt】超详细!Qt4.8.6和VS2010的配置及使用 由于QT官网一般现在进不去,所以下载一些QT版本只能通过镜像或者以前下载存储的安装包来进行,现在推荐两种方法 从参考链接中搬过来: 方案一:国内镜…...
java进阶学习脑图
今天开始分享我的第一篇博客,先放上我自己花费一个月完成的java进阶学习脑图吧! 谁都想像R大一样对JVM可以知无不言,言无不尽; 谁都想像Doug Lea一样可以参与JUC这种核心模块的开发; 但是,不能只停留在想…...
Spring 原始注解详解与实战指南
📝 1. 前言 在 Spring 框架的发展过程中,注解的引入大大简化了配置,提升了开发效率 本文将详细介绍 Spring 最初引入的核心注解,包括 Component、Controller、Service、Repository、Autowired、Qualifier 和 Value 等,…...
uniapp封装请求
在uniapp中封装HTTP请求,通常我们会使用uni.request方法。uni.request是uni-app提供的一个网络请求API,可以用来发送各种类型的HTTP请求(GET、POST、PUT、DELETE等)。下面是如何在uniapp中封装一个通用的HTTP请求方法,…...
YOLOv10 解析与地平线 征程 6 模型量化
一,YOLOv10 解析 1.简介 近些年来,研究人员对 YOLO 的架构设计、优化目标、数据增强策略等进行了探索,取得了显著进展。然而,后处理对非极大值抑制(NMS)的依赖阻碍了 YOLO 的端到端部署,并对推…...
基本网络安全的实现
基本网络安全的实现 一 :AAA AAA 是Authentication,Authorization and Accounting(认证、授权和计费)的简 称,它提供了一个用来对认证、授权和计费这三种安全功能进行配置的一致性框架, 它是对网络安全…...
ROS2 强化学习:案例与代码实战
一、引言 在机器人技术不断发展的今天,强化学习(RL)作为一种强大的机器学习范式,为机器人的智能决策和自主控制提供了新的途径。ROS2(Robot Operating System 2)作为新一代机器人操作系统,具有…...
Java数据结构第十四期:走进二叉树的奇妙世界(三)
专栏:数据结构(Java版) 个人主页:手握风云 目录 一、二叉树OJ练习题 1.1. 相同的树 1.2. 另一棵树的子树 1.3. 翻转二叉树 1.4. 平衡二叉树 1.5. 对称二叉树 一、二叉树OJ练习题 1.1. 相同的树 判断两棵树是否相同,我们是否只能遍历一…...
GO 进行编译时插桩,实现零码注入
Go 编译时插桩 Go 语言的编译时插桩是一种在编译阶段自动注入监控代码的技术,目的是在不修改业务代码的情况下,实现对应用程序的监控和追踪。 基本原理 Go 编译时插桩的核心思想是通过在编译过程中对源代码进行分析和修改,将监控代码注入到…...
《炎龙骑士团 1 邪神之封印》游戏信息
发行公司:1994 年由汉堂国际资讯公司发行。 游戏类型:回合制角色扮演游戏 故事背景 远古之战:在远古时代,圣族与魔族爆发大战,魔族领导者大邪神力量强大,圣族处于下风。圣族派出十二战士突袭,虽…...
本地大模型编程实战(23)用智能体(Agent)实现基于SQL数据构建问答系统(2)
本文将用 智能体(Agent) 实现对 SQLite 数据库的查询:用户用自然语言提出问题,智能体也用自然语言根据数据库的查询结果回答问题。 本次将分别在英文、中文环境下,使用 qwen2.5 、 MFDoom/deepseek-r1-tool-calling:7b 以及 llama3.1 做实验。…...
Flash-03
1-问题:Flash软件画两个图形,若有部分重合则变为一个整体 解决方法1:两个图形分属于不同的图层 解决方法2:将每个图形都转化为【元件】 问题2:元件是什么? 在 Adobe Flash(现在称为 Adobe Anim…...
防火墙双机热备---VRRP,VGMP,HRP(超详细)
双机热备技术-----VRRP,VGMP,HRP三个组成 注:与路由器VRRP有所不同,路由器是通过控制开销值控制数据包流通方向 防火墙双机热备: 1.主备备份模式 双机热备最大的特点就是防火墙提供了一条专门的备份通道(心…...
PC端-发票真伪查验系统-Node.js全国发票查询接口
在现代企业的财务管理中,发票真伪的验证至关重要。随着电子发票的普及,假发票问题日益严峻,如何高效、准确的对发票进行真伪查验,已经成为各类企业在日常运营中必须解决的关键问题。翔云发票查验接口做企业财务管理、税务合规的好…...
3.1部署filebeat:5044
beats是ELK体系中新增的一个工具,, 属于一个轻量的日志采集器。 1.安装(每台) # tar xf filebeat-6.4.1-linux-x86_64.tar.gz # mv filebeat-6.4.1-linux-x86_64 /usr/local/filebeat #yum -y install httpd #systemctl start httpd 2.测试…...
在 Windows 上配置 Ollama 服务并开放局域网访问
为了在局域网内共享 Ollama 服务,我们需要完成以下两步: 1、设置 Ollama 的环境变量 OLLAMA_HOST,使其监听局域网的 IP 地址。 (1) 配置 Ollama 服务的监听地址 Ollama 服务使用环境变量 OLLAMA_HOST 来指定监听的地…...
C#快速调用DeepSeek接口,winform接入DeepSeek查询资料 C#零门槛接入DeepSeek C#接入DeepSeek源代码下载
下载地址<------完整源码 在数字化转型加速的背景下,企业应用系统对智能服务的需求日益增长。DeepSeek作为先进的人工智能服务平台,其自然语言处理、图像识别等核心能力可显著提升业务系统的智能化水平。传统开发模式下,C#开发者需要耗费大…...
解决后端跨域问题
目录 一、什么是跨域问题? 1、跨域问题的定义 2、举例 3、为什么会有跨域问题的存在? 二、解决跨域问题 1、新建配置类 2、编写代码 三、结语 一、什么是跨域问题? 1、跨域问题的定义 跨域问题(Cross-Origin Resource Sh…...
【教程】使用docker+Dify搭建一个本地知识库
现在AI火的一塌糊涂,再不搭建一个自己的AI知识库就有点落伍了,这里我是自己的windows11电脑。用了dockerdifydeepseek。 一、安装docker 网址:https://www.docker.com/ 什么是docker? Docker 是一种开放源代码的容器化平台&…...
微信小程序数据绑定与事件处理:打造动态交互体验
在上一篇中,我们学习了如何搭建微信小程序的开发环境并创建了一个简单的“Hello World”页面。然而,一个真正的小程序不仅仅是静态内容的展示,它需要与用户进行动态交互。本文将深入探讨微信小程序中的数据绑定和事件处理机制,通过…...
Spring MVC 的执行流程解析:从用户请求到响应返回
Spring MVC 是一种基于 Model-View-Controller 设计模式的 Web 框架,用于处理用户请求、执行相应的业务逻辑并返回响应。它广泛应用于 Java Web 开发,提供了灵活的架构和丰富的功能。 本文将详细介绍 Spring MVC 的执行流程,帮助你理解它是如…...
c++day5
作业: 编写一个如下场景: 有一个英雄Hero类,私有成员,攻击,防御,速度,生命值,以及所有的set get 方法 编写一个 武器 Weapon 类,拥有私有成员攻击力,以及set …...
Deepseek 实战全攻略,领航科技应用的深度探索之旅
想玩转 Deepseek?这攻略别错过!先带你了解它的基本原理,教你搭建运行环境。接着给出自然语言处理、智能客服等应用场景的实操方法与代码。还分享模型微调、优化技巧,结合案例加深理解,让你全面掌握,探索科技…...
公共数据授权运营模式研究(总体框架、主要模式及发展趋势)
本报告以公共数据运营模式为核心,以释放公共数据价值为目标,深入分析公共数据概念及特征,厘清公共数据运营的内涵及本质,提出纵深分域数据要素市场运营体系的总体思路,构建了一座(一个数据底座)…...
本地开发用ASP.NET Core Web API项目创建及测试
1. 服务端代码(C#) 1.1 创建ASP.NET Core Web API项目 打开Visual Studio 2022。 选择“创建新项目”。 选择“ASP.NET Core Web API”模板,点击“下一步”。 输入项目名称(如OracleApi),选择项目位置&…...
【虚拟仪器技术】labview操作指南和虚拟仪器技术习题答案(一)
今天是2025年2月24日,画的是fate/Grand Order里面的阿尔托莉雅.卡斯特,武内老师的画。 目录 第1章 第2章 第3章 第4章 第5章 关注作者了解更多 我的其他CSDN专栏 毕业设计 求职面试 大学英语 过程控制系统 工程测试技术 虚拟仪器技术 可编程…...