runtime從入門到精通(七)—— 自動歸檔和解檔
由於文章篇幅長度原因,筆者單獨用一篇文章來介紹使用runtime來實現自動歸檔和解檔。檢視完整的runtime在實際開發中的使用點選連結 ——> runtime從入門到精通(六)—— runtime在實際開發中的應用
如果你實現過自定義模型資料持久化的過程,那麼你也肯定明白,如果一個模型有許多個屬性,那麼我們需要對每個屬性都實現一遍encodeObject
和decodeObjectForKey
方法,如果這樣的模型又有很多個,這還真的是一個十分麻煩的事情。下面來看看簡單的實現方式。
假設現在有一個Movie類,有3個屬性,它的h
檔案這這樣的
#import <Foundation/Foundation.h>
//1. 如果想要當前類可以實現歸檔與反歸檔,需要遵守一個協議NSCoding
@interface Movie : NSObject<NSCoding>
@property (nonatomic, copy) NSString *movieId;
@property (nonatomic, copy) NSString *movieName;
@property (nonatomic, copy) NSString *pic_url;
@end
如果是正常寫法, m
檔案應該是這樣的:
#import "Movie.h"
@implementation Movie
- (void )encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_movieId forKey:@"id"];
[aCoder encodeObject:_movieName forKey:@"name"];
[aCoder encodeObject:_pic_url forKey:@"url"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.movieId = [aDecoder decodeObjectForKey:@"id" ];
self.movieName = [aDecoder decodeObjectForKey:@"name"];
self.pic_url = [aDecoder decodeObjectForKey:@"url"];
}
return self;
}
@end
如果這裡有100個屬性,那麼我們也只能把100個屬性都給寫一遍。
不過你會使用runtime後,這裡就有更簡便的方法。
下面看看runtime的實現方式:
#import "Movie.h"
#import <objc/runtime.h>
@implementation Movie
- (void)encodeWithCoder:(NSCoder *)encoder
{
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Movie class], &count);
for (int i = 0; i<count; i++) {
// 取出i位置對應的成員變數
Ivar ivar = ivars[i];
// 檢視成員變數
const char *name = ivar_getName(ivar);
// 歸檔
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[encoder encodeObject:value forKey:key];
}
free(ivars);
}
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Movie class], &count);
for (int i = 0; i<count; i++) {
// 取出i位置對應的成員變數
Ivar ivar = ivars[i];
// 檢視成員變數
const char *name = ivar_getName(ivar);
// 歸檔
NSString *key = [NSString stringWithUTF8String:name];
id value = [decoder decodeObjectForKey:key];
// 設定到成員變數身上
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
@end
這樣的方式實現,不管有多少個屬性,寫這幾行程式碼就搞定了。怎麼,還嫌麻煩,下面看看更加簡便的方法:兩句程式碼搞定。
我們把encodeWithCoder 和 initWithCoder這兩個方法抽成巨集
#import "Movie.h"
#import <objc/runtime.h>
#define encodeRuntime(A) \
\
unsigned int count = 0;\
Ivar *ivars = class_copyIvarList([A class], &count);\
for (int i = 0; i<count; i++) {\
Ivar ivar = ivars[i];\
const char *name = ivar_getName(ivar);\
NSString *key = [NSString stringWithUTF8String:name];\
id value = [self valueForKey:key];\
[encoder encodeObject:value forKey:key];\
}\
free(ivars);\
\
#define initCoderRuntime(A) \
\
if (self = [super init]) {\
unsigned int count = 0;\
Ivar *ivars = class_copyIvarList([A class], &count);\
for (int i = 0; i<count; i++) {\
Ivar ivar = ivars[i];\
const char *name = ivar_getName(ivar);\
NSString *key = [NSString stringWithUTF8String:name];\
id value = [decoder decodeObjectForKey:key];\
[self setValue:value forKey:key];\
}\
free(ivars);\
}\
return self;\
\
@implementation Movie
- (void)encodeWithCoder:(NSCoder *)encoder
{
encodeRuntime(Movie)
}
- (id)initWithCoder:(NSCoder *)decoder
{
initCoderRuntime(Movie)
}
@end
我們可以把這兩個巨集單獨放到一個檔案裡面,這裡以後需要進行資料持久化的模型都可以直接使用這兩個巨集。
相關推薦
runtime從入門到精通(七)—— 自動歸檔和解檔
由於文章篇幅長度原因,筆者單獨用一篇文章來介紹使用runtime來實現自動歸檔和解檔。檢視完整的runtime在實際開發中的使用點選連結 ——> runtime從入門到精通(六)—— runtime在實際開發中的應用 如果你實現過自定義模型資料持久化
Matlab從入門到精通(七)--矩陣基本運算
31、稀疏矩陣的建立 函式 sparse 格式 S = sparse(A) %將矩陣A轉化為稀疏矩陣形式,即由A的非零元素和下標構成稀疏矩陣S。若A本身為稀疏矩陣,則返回A本身。 S = sparse(m,n) %生
CUDA從入門到精通(七):流並行
前面我們沒有講程式的結構,我想有些童鞋可能迫不及待想知道CUDA程式到底是怎麼一個執行過程。好的,這一節在介紹流之前,先把CUDA程式結構簡要說一下。 CUDA程式檔案字尾為.cu,有些編譯器可能不認識這個字尾的檔案,我們可以在VS2008的Tools->Opti
Golang從入門到精通(七):Golang控制語句之switch
基本結構 相比較 C 和 Java 等其它語言而言,Go 語言中的 switch 結構使用上更加靈活。它接受任意形式的表示式,例如: switch var1 { case val1: ... case val2:
Java入門系列(七)Java 集合框架(JCF, Java Collections Framework)
後者 try 其他 使用 元素 下一個 erl work st2 Java 集合框架圖 List、Set、Map可以看做集合的三大類 List List代表一種線性表的數據結構, List集合是有序集合,集合中的元素可以重復,訪問集合中的元素可以根據元素的索引
Next.js踩坑入門系列(七) —— 其他相關知識
Next.js踩坑入門系列 (一) Hello Next.js (二) 新增Antd && CSS (三) 目錄重構&&再談路由 (四) Next.js中期填坑 (五) 引入狀態管理Redux (六) 再次重構目錄 (七) 其他相關知識 獲
Docker入門教程(七)Docker API
【編者的話】DockerOne組織翻譯了Flux7的Docker入門教程,本文是系列入門教程的第七篇,重點介紹了Docker Registry API和Docker Hub API。 縱觀我們的Docker系列教程,我們已經討論了很多重要的Docker元件與命令。在本文中,我們將繼續深入學習Do
Spring Boot 初級入門教程(七) —— 日誌分類備份
在上一篇《Spring Boot 初級入門教程(二) —— 日誌備份》中,只是簡單說明了下日誌的備份方法,並沒有做更多的配置說明,這篇主要說一下如何分類備份不同的日誌。 一、修改日誌配置檔案的檔名。 上篇中,建立的日誌檔名為 logback.xml,開始配置前,想把檔名修改一下
Android入門筆記(七)
七、工具欄的使用 7.1 工具欄選單的建立 (1)在 res/menu 中建立資源型別為 Menu 且命名同所在佈局檔案保持一致。 (2)在 選單資原始檔中使用 xmlns 標籤定義全新的 app 名稱空間,並在 showAsAction 屬性中使用,這主要是出於相
Linux小小白入門教程(七):vi文字編輯命令
以下操作在Linux終端進行。Linux因為許可權非常嚴格,所以暫時所有的命令操作全部是在/home資料夾下的/yangjw資料夾下進行。/yangjw資料夾就是登入使用者名稱所在的資料夾,出了此資料
Node學習入門篇(七):Connect自帶的中介軟體
本章內容 解析cookie、請求主體和查詢字串的中介軟體 實現Web程式核心功能的中介軟體 處理Web程式安全的中介軟體 提供靜態檔案服務的中介軟體 解析cookie、請求主體和查詢字串的中介軟體 常用
學習Qt之基礎篇——從入門開始(1)
Qt 簡介 Qt是一個跨平臺的C++應用程式開發框架,被廣泛用於開發GUI程式。 Qt有豐富的 API且面向物件。Qt是自由且開放原始碼的軟體,在GNU較寬鬆公共許可證條款下發布。支援廣泛的編譯器,包括GCC的C++編譯器和Visual Studio。 Q
程式設計師的機器學習入門筆記(七):推薦系統入門介紹
介紹 背景 隨著網際網路行業的井噴式發展,獲取資訊的方式越來越多,人們從主動獲取資訊逐漸變成了被動接受資訊,資訊量也在以幾何倍數式爆發增長。舉一個例子,PC時代用google reader,常常有上千條未讀部落格更新;如今的微信公眾號,也有大量的紅點未閱
RPC入門總結(七)Thrift+Zookeeper實現服務治理
一、Thrift的弊端 Thrift(或者說所有的純粹的RPC框架都存在)的一大弊端是其靜態性。 由於Thrift使用IDL定義RCP 呼叫介面,實現跨語言性。那麼一旦當業務發生變化後需要重新定義介面時Thrift無法保證高可用,而且Thrift不提供對多節點的可用
Ansible入門篇(七):Hadoop自動化安裝
Hadoop是一個由Apache基金會所開發的分散式系統基礎架構,主要用於儲存和計算。 Hadoop安裝包下載 到Hadoop官網下載對應版本的安裝包,本文以hadoop 2.7.5為例。 將下載好的hadoop-2.7.5.tar.gz上傳到/opt/ansible/
Dynamics CRM 365零基礎入門學習(七)Dynamics 365 DataMigrationUtility tool使用
SDK裡有個工具叫DataMigrationUtility,這個工具適合兩個CRM系統之間的資料遷移。例如:在專案上線之初會做資料初始化的工作,一般這個工作會在UAT開始前完成,當UAT完成之後再把這部分初始化資料遷移到生產環境。那我費了半天勁把資料匯入UAT,難道還要重複一次匯入正式環境嗎
OpenCV入門筆記(七) 文字區域的提取
前面我們已經學了一些OpenCV中基本的圖片處理的知識,可以拿來做一些小應用。比如怎樣從一張圖片中,把文字圈出來。這一步驟對OCR(Optical Character Recognition)非常有用,因為一般的OCR引擎只是拿來識別文字,並沒有對圖片做預處理,因此精度可能會收到圖片質量影響。 當然,
【PP生產訂單】入門介紹(七)
生產訂單列印標準功能:訂單下達之後才可以列印。 事務程式碼:CO04N-列印 後臺需要進行設定:標準的Form設定 設定非常靈活,但是使用的不多,更好的方式可以ABAP自行開發。 下面就開始介紹訂單的發料。 著重要介紹的是訂單的元件明細裡面的幾個欄位
Lucene6入門教程(七)多目錄多執行緒索引/檢索
在使用lucene6 的時候,會遇到多目錄多執行緒的索引構建和檢索(查詢)情況。 把不同型別的資料放到同一個索引檔案中,這是不現實的,而且,除了記憶體索引,建立多目錄索引也能提高索引速度,這是因為,一個索引目錄只能有一把鎖,那如果有多個索引目錄,每個索引目
基於PyTorch的深度學習入門教程(七)——PyTorch重點綜合實踐
前言 PyTorch提供了兩個主要特性: (1) 一個n維的Tensor,與numpy相似但是支援GPU運算。 (2) 搭建和訓練神經網路的自動微分功能。 我們將會使用一個全連線的ReLU網路作為例項。該網路有一個隱含層,使用梯度下降來訓練,目標是最小化