亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS中創建Model的最佳實踐記錄

2019-10-21 18:39:31
字體:
來源:轉載
供稿:網友

前言

作為一個優秀的程序員,或者想成為優秀的程序員,最基本的你得有MVC編程思想,那么你就要對JSON獲取的數據建Model,將service和controller層都分離,從而做到低耦合?,F在有很多利用runtime能快速的將json數據轉為一個Model。但是我在做項目的時候,發現創建Model(特別是屬性特多的)寫屬性代碼很浪費時間,降低了編程效率。后來我自己就寫了個好玩的能省去時間創建Model的一個方法,下面話不多說了,來一起看看詳細的介紹吧

Immutable Model

我們以UserModle為例,我們可以像這樣創建:

public class UserModel: NSObject {  public var userId: NSNumber public var name: String? public var email: String? public var age: Int? public var address: String?  init(userId: NSNumber) {    self.userId = userId    super.init() }}

用的時候可以像這樣:

let userModel = UserModel(userId: 1)user.email = "335050309@qq.com"user.name = "roy"user.age = 27user.address = "上海市楊浦區"

這樣創建一個User對象好處是彈性很大,我可以隨意選擇設定某個property的值,但是背后同樣帶有很大的缺點,就是這個Model變得異常開放,不安分,這種Model我們一般叫Mutable Model。有的時候我們需要Mutable Model,但大部分的時候出于數據安全和解耦考慮我們不希望創建的property在外部可以隨意改變,在初始化后不可變的Model叫做Immutable Model,在開發中我的建議盡量使用Immutable Model。我們通過把property設置成readonly,在Swift可以用let或者private(set)。也就是這樣:

public class UserModel: NSObject {  public let userId: NSNumber public private(set) var name: String? public private(set) var email: String? public private(set) var age: Int? public private(set) var address: String? }

那么怎么寫初始化方法呢?

Initializer mapping arguments to properties

當我們把property設置成readonly后,我們只能在init的時候賦值,這個時候就變成這樣:

public class User: NSObject {  public var userId: NSNumber public var name: String? public var email: String? public var age: Int? public var address: String?  init(userId: NSNumber, name: String?, email: String, age: Int, address: String) {    self.userId = userId    super.init()    self.name = name  self.email = email  self.age = age  self.address = address }}

使用的時候就變成這樣:

let user = User.init(userId: 1, name: "335050309@qq.com", email: "roy", age: 27, address: "上海市楊浦區")

這樣創建Model安全可靠,大多數時候是有效的,但是也有一些缺點:

  • 如果property很多,init方法就有很多形參,然后變得又臭又長。
  • 有的時候我們只需要Model的某些property,這樣我們可能為各個不同的需求寫不同的init方法,最終讓UserModel變得很龐大。

Initializer taking dictionary

初始化的時候注入一個字典,就是下面的樣子:

public class UserModel: NSObject {  public let userId: NSNumber public private(set) var name: String? public private(set) var email: String? public private(set) var age: Int? public private(set) var address: String?  init(dic: NSDictionary) {    self.userId = (dic["userId"] as? NSNumber)!    super.init()    self.name = dic["name"] as? String  self.email = dic["email"] as? String  self.age = dic["age"] as? Int  self.address = dic["address"] as? String }}

很顯然這解決上一種第一個缺點,但是還是有一個不足之處:

  • 如果字典沒有某個屬性對應的key的時候會崩潰,編譯器并不能幫助我們排查這種運行時的崩潰。
  • 不能很好的滿足某些時候只需要Model的某些property的需求。

Mutable subclass

我們看看Improving Immutable Object Initialization in Objective-C關于這個是怎么描述的

We end up unsatisfied and continue our quest for the best way to initialize immutable objects. Cocoa is a vast land, so we can – and should – steal some of the ideas used by Apple in its frameworks. We can create a mutable subclass of Reminder class which redefines all properties as readwrite:

@interface MutableReminder : Reminder <NSCopying, NSMutableCopying>@property (nonatomic, copy, readwrite) NSString *title;@property (nonatomic, strong, readwrite) NSDate *date;@property (nonatomic, assign, readwrite) BOOL showsAlert;@end

Apple uses this approach for example in NSParagraphStyle and NSMutableParagraphStyle. We move between mutable and immutable counterparts with -copy and -mutableCopy. The most common case matches our example: a base class is immutable and its subclass is mutable.

The main disadvantage of this way is that we end up with twice as many classes. What's more, mutable subclasses often exist only as a way to initialize and modify their immutable versions. Many bugs can be caused by using a mutable subclass by accident. For example, a mental burden shows in setting up properties. We have to always check if a mutable subclass exists, and if so use copy modifier instead of strong for the base class.

大致意思是創建一個可變子類,它將所有屬性重新定義為readwrite。這種方式的主要缺點是我們最終得到兩倍的類。而且,可變子類通常僅作為初始化和修改其不可變版本的方式存在。偶然使用可變子類可能會導致許多錯誤。例如,在設置屬性時會出現心理負擔。我們必須始終檢查是否存在可變子類。

還有一點這種方式只能在Objective-C中使用。

Builder pattern

Builder pattern 模式需要我們使用一個Builder來創建目標對象,目標對象的property依舊是readonly,但是Builder的對應property卻可以選擇為readwrite。依舊用UserModel為例,我們需要為其進行適當的改造,改造之后:

typealias UserModelBuilderBlock = (UserModelBuilder) -> UserModelBuilderpublic class UserModel: NSObject{  public let userId: NSNumber public private(set) var name: String? public private(set) var email: String? public private(set) var age: Int? public private(set) var address: String?  init(userId: NSNumber) {  self.userId = userId    super.init() }  convenience init(userId: NSNumber ,with block: UserModelBuilderBlock){   let userModelBuilder = block(UserModelBuilder.init(userId: userId))  self.init(userId: userModelBuilder.userId)  self.email = userModelBuilder.email  self.name = userModelBuilder.name  self.age = userModelBuilder.age  self.address = userModelBuilder.address }}

之后是對應的Builder

class UserModelBuilder: NSObject {  public let userId: NSNumber public var name: String? public var email: String? public var age: Int? public var address: String?  init(userId: NSNumber) {    self.userId = userId  super.init() }}

然后可以像下面這樣使用:

let userModle = UserModel(userId: 1) { (builder) -> UserModelBuilder in  builder.email = "335050309@qq.com" builder.name = "roy" builder.age = 27 builder.address = "上海市楊浦區" return builder}

這種方式雖然我們需要為Model再創建一個Builder,略顯啰嗦和復雜,但是當property較多,對Model的需求又比較復雜的時候這又確實是一種值得推薦的方式。

以上全是Swift的代碼實現,下面我再貼上對應的OC代碼

#import <Foundation/Foundation.h>@interface RUserModelBuilder : NSObject@property (nonatomic, strong, readwrite, nonnull) NSNumber *userId;@property (nonatomic, copy, readwrite, nullable) NSString *name;@property (nonatomic, copy, readwrite, nullable) NSString *email;@property (nonatomic, copy, readwrite, nullable) NSNumber *age;@property (nonatomic, copy, readwrite, nullable) NSString *address;@endtypedef RUserModelBuilder *__nonnull(^RUserModelBuilderBlock)(RUserModelBuilder *__nonnull userModelBuilder);@interface RUserModel : NSObject@property (nonatomic, strong, readonly, nonnull) NSNumber *userId;@property (nonatomic, copy, readonly, nullable) NSString *name;@property (nonatomic, copy, readonly, nullable) NSString *email;@property (nonatomic, copy, readonly, nullable) NSNumber *age;@property (nonatomic, copy, readonly, nullable) NSString *address;+ (nonnull instancetype)buildWithBlock:(nonnull RUserModelBuilderBlock)builderBlock;@end
#import "RUserModel.h"@implementation RUserModelBuilder@end@interface RUserModel ()@property (nonatomic, strong, readwrite, nonnull) NSNumber *userId;@property (nonatomic, copy, readwrite, nullable) NSString *name;@property (nonatomic, copy, readwrite, nullable) NSString *email;@property (nonatomic, copy, readwrite, nullable) NSNumber *age;@property (nonatomic, copy, readwrite, nullable) NSString *address;@end@implementation RUserModel#pragma mark - NSCopying+ (nonnull instancetype)buildWithBlock:(nonnull RUserModelBuilderBlock)builderBlock { RUserModelBuilder *userModelBuilder = builderBlock([[RUserModelBuilder alloc] init]); RUserModel *userModel = [[RUserModel alloc] init]; userModel.userId = userModelBuilder.userId; userModel.name = userModelBuilder.name; userModel.email = userModelBuilder.email; userModel.age = userModelBuilder.age; userModel.address = userModelBuilder.address; return userModel;}@end

demo地址:ImmutableModel

參考文章:

Improving Immutable Object Initialization in Objective-C

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美国产日韩在线| 91精品在线观看视频| 久久激情视频久久| 午夜精品久久17c| 亚洲男人av在线| 欧美大片va欧美在线播放| 91免费欧美精品| 国产精品一区二区3区| 国产亚洲激情在线| 国产成人精品av在线| 超薄丝袜一区二区| 91av在线国产| 国产精品电影一区| 91麻豆桃色免费看| 亚洲男人天堂手机在线| 亚洲国内高清视频| 国产精品久在线观看| 色综合色综合网色综合| 亚洲色图美腿丝袜| 欧美伊久线香蕉线新在线| 日韩一区二区欧美| 美日韩精品免费观看视频| 色婷婷综合久久久久中文字幕1| 自拍偷拍亚洲在线| 亚洲自拍偷拍一区| 精品无人国产偷自产在线| 欧美性理论片在线观看片免费| 国产精品入口尤物| 成人xvideos免费视频| 美女福利视频一区| 亚洲精品久久久久久久久久久久久| 国产69精品久久久久9999| 亚洲成色777777在线观看影院| 亚洲自拍偷拍色图| 亚洲国产欧美一区二区三区同亚洲| 国产成人自拍视频在线观看| 国产精品极品美女在线观看免费| 亚洲视频在线观看网站| 日韩激情第一页| 日韩视频在线观看免费| 欧美精品激情在线观看| 欧美有码在线观看视频| 中文字幕在线精品| 亚洲美女在线看| 岛国av午夜精品| 97国产一区二区精品久久呦| 亚洲色无码播放| 欧美极品美女视频网站在线观看免费| 国产男人精品视频| 亚洲精品动漫100p| 亚洲欧美国产视频| 色偷偷888欧美精品久久久| 国产精品88a∨| 在线观看日韩专区| 国产精品一区=区| 高清欧美一区二区三区| 亚洲福利视频网| 永久免费精品影视网站| 奇米四色中文综合久久| 欧美精品精品精品精品免费| 精品人伦一区二区三区蜜桃网站| 国产一区二区三区丝袜| 92看片淫黄大片欧美看国产片| 性欧美办公室18xxxxhd| 欧美精品18videos性欧| 国产精品影院在线观看| 成人免费视频网| 欧美色视频日本高清在线观看| 美日韩精品免费观看视频| 国产精品高精视频免费| 欧美色欧美亚洲高清在线视频| 91久久精品国产| 亚洲精品456在线播放狼人| 亚洲国产99精品国自产| 欧美性极品xxxx娇小| 欧洲一区二区视频| 国产精品国语对白| 国产精品v日韩精品| 欧美韩日一区二区| 亚洲欧美日韩网| 欧美华人在线视频| 中文字幕日韩在线视频| 在线色欧美三级视频| 亚洲欧美一区二区精品久久久| 国产精品成人一区二区三区吃奶| 亚洲国产第一页| 欧美性猛交xxxx黑人猛交| 精品一区二区三区四区在线| 中文字幕日韩精品在线观看| 亚洲国产精品网站| 国产精品黄色影片导航在线观看| 在线播放日韩精品| 久久99精品久久久久久琪琪| 国产91热爆ts人妖在线| 日韩在线视频免费观看高清中文| 日韩激情视频在线播放| 久久香蕉国产线看观看av| 日韩大陆毛片av| 色婷婷久久一区二区| 日韩av快播网址| 欧美视频一二三| 精品国产精品三级精品av网址| 欧美激情国产高清| 亚洲图片欧美午夜| 最新日韩中文字幕| 日韩欧美一区视频| 色偷偷888欧美精品久久久| 国产精品视频区1| 亚州av一区二区| 国产精品一区二区久久| 国内精品国产三级国产在线专| 国产精品国模在线| 日本午夜精品理论片a级appf发布| 久久免费高清视频| 欧美重口另类videos人妖| 亚洲最大福利网站| 亚洲精品美女久久久久| 亚洲精品国产拍免费91在线| 91极品女神在线| 欧美日韩在线视频首页| 97免费视频在线播放| 亚洲第一免费播放区| 国产成人精品视频在线| 亚洲国内精品在线| 成人h猎奇视频网站| 国产精品女主播视频| 久久国产天堂福利天堂| 精品久久久久久久大神国产| 精品亚洲精品福利线在观看| 久久久国产精品视频| 国产不卡精品视男人的天堂| 亚洲日本成人网| 欧美大片免费观看在线观看网站推荐| 亚洲色图50p| 欧美男插女视频| 国产欧美精品一区二区三区介绍| 国产精品女人网站| 亚洲精品电影久久久| 97国产在线观看| 韩国美女主播一区| 国内精久久久久久久久久人| 欧美老少做受xxxx高潮| 超碰精品一区二区三区乱码| 成人午夜在线影院| 国产aⅴ夜夜欢一区二区三区| 日韩亚洲在线观看| 国产精品久久久久久久久免费| 午夜精品三级视频福利| 51精品国产黑色丝袜高跟鞋| 日韩精品福利在线| 在线观看日韩视频| 精品国产一区二区三区久久狼5月| 欧美性xxxx极品hd欧美风情| 国产精品成人国产乱一区| 久久精品中文字幕电影| 国产99久久精品一区二区| 日韩中文视频免费在线观看| 欧美成人激情视频免费观看| 中文字幕日韩在线观看| 成人国产精品av| 26uuu国产精品视频| 国语自产精品视频在线看一大j8| 国产精品久久久久久久久久久不卡| 亚洲最大av网站|