《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之中了。若接口背后有多個不同的實現類,又不想指明具體使用哪個,可以考慮用這個方法,此概念被稱為“匿名對象”。

有時對象類型不重要,重要的是有沒有實現某些方法,在此情況下,也可以使用這些“匿名類型”來表達這一概念。

比如對受委托者的定義:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71902.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71902.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71902.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++程序員內功修煉——Linux C/C++編程技術匯總

在軟件開發的宏大版圖中&#xff0c;C 語言宛如一座巍峨的高山&#xff0c;吸引著無數開發者攀登探索。而 Linux 操作系統&#xff0c;以其開源、穩定、高效的特性&#xff0c;成為了眾多開發者鐘愛的開發平臺。將 C 與 Linux 相結合&#xff0c;就如同為開發者配備了一把無堅不…

數據庫索引:缺點與類型全解析

在數據庫的世界里&#xff0c;索引就像是一本書的目錄&#xff0c;它能幫助我們快速定位到所需的數據&#xff0c;極大地提升查詢效率。然而&#xff0c;就如同任何事物都有兩面性一樣&#xff0c;索引也并非完美無缺。今天&#xff0c;我們就來深入探討一下索引的缺點以及常見…

【python】提取word\pdf格式內容到txt文件

一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""讀取 PDF 文件內容:param file_path: PDF 文件路徑:return: 文件內容文本"""try:text ext…

嵌入式八股文(五)硬件電路篇

一、名詞概念 1. 整流和逆變 &#xff08;1&#xff09;整流&#xff1a;整流是將交流電&#xff08;AC&#xff09;轉變為直流電&#xff08;DC&#xff09;。常見的整流電路包括單向整流&#xff08;二極管&#xff09;、橋式整流等。 半波整流&#xff1a;只使用交流電的正…

精選案例展 | 智己汽車—全棧可觀測驅動智能化運營與成本優化

本案例為“觀測先鋒 2024 可觀測平臺創新應用案例大賽”精選案例&#xff0c;同時榮獲IT168“2024技術卓越獎評選-年度創新解決方案”獎。 項目背景 近年來&#xff0c;中國汽車行業進入轉型升級階段&#xff0c;智能網聯技術成為行業發展的核心。車聯網、自動駕駛等技術的加速…

速通HTML

目錄 HTML基礎 1.快捷鍵 2.標簽 HTML進階 1.列表 a.無序列表 b.有序列表 c.定義列表 2.表格 a.內容 b.合并單元格 3.表單 a.input標簽 b.單選框 c.上傳文件 4.下拉菜單 5.文本域標簽 6.label標簽 7.按鈕標簽 8.無語義的布局標簽div與span 9.字符實體 HTML…

【Python模塊】——pymysql

pymysql是python操作mysql的標準庫&#xff0c;可以通過pip install快速導入pymysql包操作數據庫 使用pymysql操作mysql 簡單demo import pymysql connect pymysql.connect(host"localhost",port3306,user"root",password"root",database&quo…

IP離線庫助力破解網絡反詐難題

毫秒級響應識別異常訪問 IP離線庫集成全球全量IP地址的詳細信息&#xff0c;包括地理地址查詢、運營商、經緯度、代理識別等多種維度數據。例如&#xff1a; 當用戶賬號頻繁從北京、越南等多地IP登錄時&#xff0c;系統將自動觸發風險預警&#xff1b; 檢測到訪問IP為已知機…

lattice hdl實現spi接口

在lattice工具鏈中實現SPI接口通常涉及以下步驟: 定義硬件SPI接口的管腳。配置SPI時鐘和模式。編寫SPI主機或從機的控制邏輯。 展示了如何在Lattice工具鏈中使用HDL語言(例如Verilog)來配置SPI接口: lattice工程 頂層:spi_slave_top.v `timescale 1ns/ 1ps module spi_…

Spring 循環依賴解析與解決方案

文章目錄 1. 什么是循環依賴&#xff1f;1.1 概念解析1.2 示例代碼 2. 循環依賴的類型2.1 構造器循環依賴&#xff08;不可解決 ?&#xff09;2.2 Setter 方式或 Autowired 方式的循環依賴&#xff08;可解決 ?&#xff09; 3. 解決循環依賴的方式3.1 方式一&#xff1a;使用…

Cesium@1.126.0,創建3D瓦片,修改樣式

第一步&#xff1a;添加3D建筑 Cesium.createOsmBuildingsAsync()這是一個異步方法&#xff0c;所以要寫在一個異步函數里 創建一個函數 const create3DBuilding async (viewer) > {try {// 添加3D建筑const tileset await Cesium.createOsmBuildingsAsync();viewer.scen…

力扣-貪心-1005 k次取反后最大化的數組和

思路 找到絕對值最大的&#xff0c;然后如果是負數就變成正的&#xff0c;所有數遍歷完之后&#xff0c;有兩種情況&#xff0c;一種是k已經為0了&#xff0c;不需要再取反了&#xff0c;一種是所有數都為正數&#xff0c;k不為0&#xff0c;此時對絕對值最小的數操作即可 代…

vue2項目打包后js文件過大, 首次加載緩慢

vue2項目打包后js文件過大, 首次加載緩慢 安裝插件 npm i compression-webpack-plugin6.1.1 -D配置vue.config.js const CompressionWebpackPlugin require(compression-webpack-plugin)module.exports {configureWebpack: {plugins:[new CompressionWebpackPlugin({filen…

高級SQL技術在Python項目中的應用:ORM與深度性能優化

引言 在現代Python項目開發中,數據庫交互遠不止是數據的簡單存取,它已成為構建高性能、可維護應用的核心瓶頸和關鍵能力所在。 僅僅依賴基礎SQL查詢,雖然入門簡單,卻難以應對日益增長的應用挑戰。這些挑戰主要體現在以下幾個方面: 性能瓶頸: 數據量劇增: 從百萬到數十億乃…

基于 C++ Qt 的 Fluent Design 組件庫 QFluentWidgets

簡介 QFluentWidgets 是一個基于 Qt 的 Fluent Designer 組件庫&#xff0c;內置超過 150 個開箱即用的 Fluent Designer 組件&#xff0c;支持亮暗主題無縫切換和自定義主題色。 編譯示例 以 Qt5 為例&#xff08;Qt6 也支持&#xff09;&#xff0c;將 libQFluentWidgets.d…

抖音視頻如何下載保存去水印

隨著短視頻平臺的興起&#xff0c;抖音作為國內最受歡迎的短視頻平臺之一&#xff0c;吸引了大量用戶上傳和觀看各種創意視頻。許多用戶在瀏覽抖音視頻時&#xff0c;往往會想要保存一些有趣或精彩的視頻片段&#xff0c;但抖音視頻通常會有水印&#xff0c;影響觀看體驗。為了…

React 源碼揭秘 | 更新隊列

前面幾篇遇到updateQueue的時候&#xff0c;我們把它先簡單的當成了一個隊列處理&#xff0c;這篇我們來詳細討論一下這個更新隊列。 有關updateQueue中的部分&#xff0c;可以見源碼 UpdateQueue實現 Update對象 我們先來看一下UpdateQueue中的內容&#xff0c;Update對象&…

[SQL] 事務的四大特性(ACID)

&#x1f384;事務的四大特性 以下就是事務的四大特性&#xff0c;簡稱ACID。 原子性&#x1f4e2;事務時不可分割的最小操作單元&#xff0c;要么全部成功&#xff0c;要么全部失敗。一致性&#x1f4e2;事務完成后&#xff0c;必須使所有的數據都保持一致隔離性&#x1f4e2…

DeepSeek 提示詞:基礎結構

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

如何使用 Python 連接 MySQL 數據庫?

在Python開發中&#xff0c;連接MySQL數據庫是一個常見的需求。 我們可以使用多種庫來實現這一功能&#xff0c;其中最常用的是mysql-connector-python和PyMySQL。 下面我將詳細介紹如何使用這兩個庫來連接MySQL數據庫&#xff0c;并提供一些實際開發中的建議和注意事項。 1…