国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS創建對象的不同姿勢詳解

2020-07-26 02:56:14
字體:
來源:轉載
供稿:網友

前言

在寫 iOS 代碼的時候,怎么樣去 new 一個新對象出來,都有一些講究在里面。使用不同的姿勢去創建對象,對后期維護所造成的影響會存在細微的差別。

init 創建

在之前一篇分析 iOS 代碼耦合的文章中,提到過當我們給一個對象的 property 賦值的時候,通過 init 方法傳入參數來初始化 property 會讓我們的代碼更可靠。

有些人在定義帶 property 的 class 的時候,會這樣定義:

@interface User : NSObject@property (nonatomic, strong) NSNumber*     userID;@end

使用的時候如下:

User* user = [[User alloc] init];user.userID = @1000;

尤其是在定義 model 的時候,很容易寫出這種,先 init,而后挨個給 property 賦值的代碼。這種代碼的問題在于 property 對于外部是可寫的,property 處于隨時可能變化的狀態。之前不少篇文章中都強調過 immutable 的重要性,同樣對于一個 class,我們也應該優先考慮設計成 immutable 的。

initWith 創建

如果將 property 都設置成 readonly 的,或者不暴露 property,property 的賦值都通過 initWith 的方式來初始化,就可以得到一個具備 immutable 的 class 定義了,具體到上面的例子代碼如下:

//User.h@interface User : NSObject@property (nonatomic, strong, readonly) NSNumber* userID;- (instancetype)initWithUserID:(NSNumber*)uid;@end //User.m@implementation User- (instancetype)initWithUserID:(NSNumber*)uid { self = [super init]; if (!self) {  return nil; } _userID = uid; return self;}@end

userID 在 .h 文件當中是 readonly 的,userID 只有一次被賦值的機會,即在 User 的 initWith 方法中。這種方式的好處是一旦 User 對象創建完畢之后,就處于 immutable 的狀態,property 都是不可修改的,安全可靠。

Designated initializer

Apple 為了方便開發者使用 init 方法,引入了一種名為 designated initializer 的 pattern。主要用來管理當一個 class 擁有多個 property 需要賦值的場景。比如上面我們的 User 類:

@interface User : NSObject@property (nonatomic, strong, readonly) NSNumber*     userID;@property (nonatomic, strong, readonly) NSString*     userName;@property (nonatomic, strong, readonly) NSString*     signature;@end

有些場景需要初始化 userID 和 userName,而有些場景只需要初始化 userID 和 signature,所以我們需要提供多個 initWith 方法給不同的場景使用。為了管理 initWith 方法,Apple 將 init 方法分為兩種類型:designated initializer 和 convenience initializer (又叫 secondary initializer) 。

designated initializer 只有一個,它會為 class 當中每個 property 都提供一個初始值,是最完整的 initWith 方法。convenience initializer 則可以有很多個,它可以選擇只初始化部分的 property。convenience initializer 最后到會調用到 designated initializer,所以 designated initializer 也可以叫做 final initializer。

無論我們定義何種類型的 class,給 class 中的每個 property 都賦予一個初始值是個很好的習慣,可以避免掉一些意外的 bug 產生,這也是 designated initializer 的重要職責。

在實際的項目當中,一個 class 的 property 數目可能會隨著業務的增長而增加,最后的結果就是會生成越來越多的 convenience initializer。上述的 User 類,如果是 3 個 property,極端的情況下最多可以有 7 個 init 方法。Peak君在閱讀代碼的時候,也確實看到過有些 class 定義了一連串整整齊齊擺放的 init 方法,代碼雖然看著規范,但顯得

主站蜘蛛池模板: 东宁县| 平凉市| 万州区| 柯坪县| 渭南市| 定南县| 泽库县| 北票市| 若羌县| 赤城县| 石景山区| 北辰区| 涿州市| 梅河口市| 加查县| 忻城县| 胶州市| 奈曼旗| 河津市| 泉州市| 新源县| 赤水市| 石家庄市| 潮安县| 永靖县| 紫云| 襄城县| 开封市| 梅河口市| 乌审旗| 炉霍县| 河源市| 大埔县| 乌兰县| 花垣县| 宜州市| 喜德县| 喜德县| 万年县| 本溪市| 大英县|