1. 程式人生 > >runtime從入門到精通(七)—— 自動歸檔和解檔

runtime從入門到精通(七)—— 自動歸檔和解檔

由於文章篇幅長度原因,筆者單獨用一篇文章來介紹使用runtime來實現自動歸檔和解檔。檢視完整的runtime在實際開發中的使用點選連結 ——> runtime從入門到精通(六)—— runtime在實際開發中的應用

如果你實現過自定義模型資料持久化的過程,那麼你也肯定明白,如果一個模型有許多個屬性,那麼我們需要對每個屬性都實現一遍encodeObjectdecodeObjectForKey方法,如果這樣的模型又有很多個,這還真的是一個十分麻煩的事情。下面來看看簡單的實現方式。

假設現在有一個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網路作為例項。該網路有一個隱含層,使用梯度下降來訓練,目標是最小化