1. 程式人生 > >KVC與KVO的進階使用

KVC與KVO的進階使用

本篇主要介紹鍵-值編碼KVC,鍵值觀察KVO的進階使用的一些技巧主要是一下兩個方面:

  • KVC的集合操作符
  • KVO的手動實現方式

KVC集合操作符

關於集合操作符在蘋果官方文件搜尋Collection Operators的關鍵字就可以檢視相關的文件。建議多看官方文件,本篇介紹也是以官方文件為基礎的。

如果一個物件包含一個數組或者是集合的屬性那麼使用valueForKeyPath獲取相關的屬性時可以在鍵的路徑中插入一些函式。這些函式稱為集合操作符

按照分類可以分為三類:

  • 簡單的集合操作符

    • @avg
    • @count
    • @max
    • @min
    • @sum
  • 物件操作符

    • @distinctUnionOfObjects
    • @unionOfObjects
  • 陣列和集合操作符

    • @distinctUnionOfArrays
    • @unionOfArrays
    • @distinctUnionOfSets

對於這些操作符使用的格式如下:

現在宣告一個自定義的物件如下:

@interface TestModel : NSObject
@property (nonatomic,strong) NSString *title;
@property (nonatomic,strong) NSString *detail;
@property (nonatomic,strong) NSArray *strings;
-(instancetype)init;
@end
@implementation TestModel - (instancetype)init { self = [super init]; if (self) { _title = @"title"; _detail = @"detail"; _strings = @[@{ @"number":@"2" }, @{ @"number":@"3"
}, @{ @"number":@"4" }, @{ @"number":@"5" }, @{ @"number":@"1" }, @{ @"number":@"1" }]; } return self; } @end

首先宣告一個TestModel型別的屬性

@property (nonatomic,strong) TestModel *testModel; 

@avg:遍歷集合中的元素將它們轉換為一個雙精度浮點數並返回表示它們的平均數NSNumber型別的物件

    _testModel = [[TestModel alloc] init];
    id object = [self valueForKeyPath:@"[email protected]"];
    NSLog(@"object--%@\nclass--%@",object,[object class]);

輸出:

object--2.73333333333333333333333333333333333333
class--NSDecimalNumber

@count:返回集合中物件的數量

     _testModel = [[TestModel alloc] init];
    id object = [self valueForKeyPath:@"[email protected]"];
    NSLog(@"object--%@\nclass--%@",object,[object class]);

輸出:

object--6
class--__NSCFNumber

@max與@min:返回集合中的最大值與最小值

     _testModel = [[TestModel alloc] init];
    id object = [self valueForKeyPath:@"[email protected]"];
    NSLog(@"object--%@\nclass--%@",object,[object class]);
     _testModel = [[TestModel alloc] init];
    id object = [self valueForKeyPath:@"[email protected]"];
    NSLog(@"object--%@\nclass--%@",object,[object class]);

輸出:

object--5
class--__NSCFConstantString
object--1
class--__NSCFConstantString

@sum:遍歷集合中的每一項將它們轉換為一個雙精度浮點數並返回表示它們的和NSNumber型別的物件

@distinctUnionOfObjects:返回集合中所有的物件如果有相同的物件那麼只返回一個。

     _testModel = [[TestModel alloc] init];
    id object = [self valueForKeyPath:@"[email protected]"];
    NSLog(@"object--%@\nclass--%@",object,[object class]);

輸出:

object--(
    3,
    5,
    1,
    4,
    "2.4"
)
class--__NSArrayI

陣列中屬性number為1的值有兩個此時只返回一個。

@unionOfObjects:與@distinctUnionOfObjects相反,返回所有的物件包括重複的物件。

@distinctUnionOfArrays、@unionOfArrays、@distinctUnionOfSets與上述使用方法大致相同只不過操作物件由數組裡的物件變成數組裡的集合。

KVO的手動實現方式

如果我們使用KVO時不想更改某個屬性時立刻回撥,比如更改一個屬性後想要執行某個操作,這個操作執行後才希望通過收到通知那麼此時就需要手動實現KVO監聽。

我們手動實現KVO首先要禁用系統自帶的KVO監聽,禁用的方法非常簡單在想要監聽的物件實現automaticallyNotifiesObserversForKey並返回NO即可。對於上面的自定義模型在其內部實現以下方法來達到當title屬性發生變化時不會收到通知:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
{
    if ([key isEqualToString:@"title"]) {
        return NO;
    }
    else
        return  YES;
}

手動實現KVO也是通過呼叫willChangeValueForKeydidChangeValueForKey這兩個基類方法實現的。

     _testModel = [[TestModel alloc] init];
    [_testModel addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

   _testModel.title = @"chapter";

上面的寫法因為禁用了title屬性的自動監聽功能所以當title發生變化時系統不會監聽到。

     _testModel = [[TestModel alloc] init];
    [_testModel addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

    [_testModel willChangeValueForKey:@"title"];
    _testModel.title = @"chapter";
    // do something
    [_testModel didChangeValueForKey:@"title"];

呼叫didChangeValueForKey時系統才會監聽到title已經發生變化

相關推薦

KVCKVO使用

本篇主要介紹鍵-值編碼KVC,鍵值觀察KVO的進階使用的一些技巧主要是一下兩個方面: KVC的集合操作符 KVO的手動實現方式 KVC集合操作符 關於集合操作符在蘋果官方文件搜尋Collection Operators的關鍵字就可以檢視相關的文件。

Python接口測試框架實戰自動化

格式化 取數據 連接數 數據頁面 工作 1-1 持續集成 http pos 第1章 接口測試基礎回顧 1-1 接口自動化測試從基礎到框架-導學 1-2 接口基礎知識回顧 1-3 接口測試基礎面試解答第2章 fiddler在工作中的運用 2-1 如何抓接口

已知任意平面方程,推導座標旋轉變換的結論方法(篇),願願原創。

作為本部落格《已知任意平面方程,推導座標旋轉變換的結論與方法,願願原創。》(連結:https://blog.csdn.net/tom_xuzg/article/details/83034006)的姊妹篇,本文將繼續探討,座標旋轉變換,不同之處,上一篇用了三次旋轉變換,這一篇要用兩次旋轉變換。上一篇結

iOS KVCKVO簡介

級別: ★★☆☆☆ 標籤:「iOS」「KVC」「KVO」 作者: dac_1033 審校: QiShare團隊 一、 KVC 1.1 KVC介紹 KVC是Key Value Coding的縮寫,即 鍵值編碼。 在iOS的開發中,可以通過key名直接訪問例項物件的屬性,而不需要呼叫明確的存取方法

iOS基礎知識整理之KVCKVO

如何理解KVC? 在iOS中每一個物件的建立屬性的過程中,以KVC的角度理解會建立一個對應的鍵值對,這個鍵值對的key為設定的物件的屬性值,而對於該屬性的值為對應的value值。如果存在多層呼叫關係需要用到keypath來實現。如下Person型別實力物件有1

Oracle Insert增強SQL

INSERT增強與SQL進階:一、同時向多張表中插入資料 語法: INSERT ALL INTO (表1) VALUES (查出來的欄位1, 查出來的欄位2) INTO (表2) VALUES (查出來

Django 視圖網址

ges ces 也會 視圖 ngx padding request hat 技術分享 一 、在網頁上做加減法 1. 采用 /add/?a=4&b=5 這樣GET方法進行 1 2 3 django-admin.py startproject zqxt_v

【2016/3】C++ 類物件 運算子過載 new delete 模板 繼承

類與物件: const常量哪怕棧空間資料被改 被訪問時依然是使用存於符號表的資料 建構函式的形式: 拷貝構造 Test(Test &t){} 初始化構造 Test(int d): data(d){} Test

iOS面試題庫——KVCKVO

KVC與KVO 本文將會詳解在面試中的常客——KVO實現的原理,在瞭解KVO之前我們要對KVC進行一個全面的瞭解,畢竟連官方文件都提到過: important: In order to understand key-value observing

Object-C之KVCKVO

【一】KVC鍵值編碼 KVC全稱Key Value Coding KVC由NSKeyValueCoding協議支援 用來給物件中的屬性進行賦值 幾個重要方法: FKBook *book

iOS開發筆記之七十四——FRPRAC篇(資料黑白板XYReactDataBoard的介紹)

******閱讀完此文,大概需要30分鐘****** 一、簡介 XYReactDataBoard是一款已經比較成熟的基於RAC的響應式程式設計元件,它主要用來實現任意模組之間的資料通訊,它可以替代原生的Notification、KVO,delegate、NSUserdef

Django學習(四)(檢視網址)

一.在網頁上做加減法 1. 採用 /add/?a=4&b=5 這樣GET方法進行 django-admin.py startproject zqxt_views cd zqxt_views python manage.py startapp c

Android框架之路——FloatingActionButton使用ToolBar

參考部落格: 效果演示: FAB的相關: app:fabSize設定FloatingActionButton的大小,有兩種賦值分別是 “mini” 和 “normal”,預設是normal; app:backgroundTint:Floa

ASP.NET MVC URL重寫優化(篇)-繼承RouteBase玩轉URL

在初級篇中,我們介紹瞭如何利用基於ASP.NET MVC的Web程式中的Global檔案來簡單的重寫路由。也介紹了它本身的侷限性-依賴於路由資訊中的鍵值對:   如果鍵值對中沒有的值,我們無法將其利用湊出我們想要的URL表示式。   在進階篇中,我們將介紹ASP.

mysql(二)之細談索引、分頁慢日誌

連表 組合索引 rar 偏移量 最小值 num glob 要求 for 索引 1、數據庫索引   數據庫索引是一種數據結構,可以以額外的寫入和存儲空間為代價來提高數據庫表上的數據檢索操作的速度,以維護索引數據結構。索引用於快速定位數據,而無需在每次訪問數據庫表時搜索數據

Java學習筆記——排序算法之排序(堆排序分治並歸排序)

進行 技術分享 ring http 沒有 oid 有序 重復 調整 春蠶到死絲方盡,蠟炬成灰淚始幹               ——無題 這裏介紹兩個比較難的算法: 1、堆排序 2、分治並歸排序 先說堆。 這裏請大家先自行了解完全二叉樹的數據結構。 堆是完全二叉樹。

Linq To Sql系列(六)用object的動態查詢保存log篇

directory ont 簡單 lambda表達式 bind add dbo 所有 生成 動態的生成sql語句,根據不同的條件構造不同的where字句,是拼接sql 字符串的好處。而Linq的推出,是為了彌補編程中的 Data != Object 的問題。我們又該如何實現

Python-繼承中的MROsuper

puthon摘要本文講述Python繼承關系中如何通過super()調用“父類”方法,super(Type, CurrentClass)返回CurrentClass的MRO中Type的下一個類的代理;以及如何設計Python類以便正確初始化。1. 單繼承中父類方法調用在繼承中,調用父類方法是很有必要的。調用父

Nginx-->-->原理-->Nginx+php+fastcgi的原理關系

httpd nts 記錄 返回 情況 開啟 一是 動態腳本 code 一、用戶對動態PHP網頁訪問過程 用戶瀏覽器發起對網頁的訪問:http://192.168.1.103/index.php 用戶和nginx服務器進行三次握手進行TCP連接(忽略包括nginx訪問控制

Python(3)_線程中的lock(互斥鎖、遞歸鎖、信號量)

fun 我們 bsp 控制 支持 發生 class 線程 數據操作 1、同步鎖 (Lock) 當各個線程需要訪問一個公共資源時,會出現數據紊亂 例如: 1 import threading,time 2 def sub(): 3 global num