AkvcExtension 1.0.4

AkvcExtension 1.0.4

Novo 维护。



  • Novo

LogoAkvcExtension

  • 为 KVC 扩展的 KeyPath。
  • 在 KeyPath 中用更少的代码描述复杂逻辑。减少程序员的劳动。
    1. 在 KeyPath 中直接访问结构体成员。
    2. 在 KeyPath 中使用谓词。
    3. 实现自定义函数或 @NSKeyValueOperator(@avg, @count, ...)
    4. 在 KeyPath 中直接执行类型安全的检查。
    5. 起点简单,而长度更长。
  • 用更少的代码描述复杂的逻辑,减少程序员的工作。
    1. 在 KVC 中直接访问结构体成员。
    2. 在 KVC 中使用谓词。
    3. 实现自定义函数或 @NSKeyValueOperator(@avg, @count, ...)
    4. 在 KVC 中直接进行类型安全的检查。
    5. 点个赞,好运连连。

导入

  • 将文件夹 AkvcExtension 下的所有源文件拖到您的项目中。
#import "AkvcExtension.h"
  • 或者使用 CocoaPods
pod 'AkvcExtension'
  • iOSmacOS

概述

示例

[... akvc_setValue:@(100) forExtensionPath:@"....frame->size->width"];

[... akvc_setValue:@(YES) forExtensionPath:@"...dogs.@:age<1!.smallDog"];

[... akvc_valueForExtensionPath:@"view.subviews.@:hidden == YES!.@removeFromSuperview"];

///myStarts is outlet collections
myStarts
.akvcSetValueForExtensionPath(@(NO), @"seleced")
.akvcSetValueForExtensionPathWithFormat(@(YES), @"@:tag <= %ld!.seleced", sender.tag);

内容


扩展路径

所有功能

Name                   Representation
-------------------------------------
StructPath         :   NSKeyPath->StructKey
Indexer            :   @[...]
PathFunction       :   @PathFunction
Subkey             :   <...>
Regkey             :   <$...$>
SELInspector       :   SEL(...)?
ClassInspector     :   Class(...)?
KeysAccessor       :   {KeyPath,KeyPath, ...}
PredicateFilter    :   @:...!
PredicateEvaluate  :   @:...?
-------------------------------------

结构路径

结构路径可以访问结构。

  • 使用访问器 -> 访问结构中的属性。结构访问符
@"...NSKeyPath->StructKey->StructKey";

索引器

提供了一种简化的方式来访问键路径中的数组元素。

Provides a simple way to access array elements in key path.
@[0] ; @[0,1] ;

Use the index symbol 'i' to find elements within the array range.
@[i <= 3 , i > 5];

Use the index symbol '!' You can exclude elements from an array.
@[!0,!1] ; @[i != 0 , i != 1] ; @[i<5 , 9] ; @[i<5 , !3] ;

Confirm elements and deny elements cannot exist at the same time.真假不能同时存在!
It's wrong : @[0,!1] ;

PathFunction

PathFunction 是一个自定义的 NSKeyValueOperator。自定义路径函数

[... akvc_valueForExtensionPath:@"...friendList.@sortFriends..."];

Regist PathFunction

[AkvcExtension registFunction:@"sortFriends" withBlock:^id(id  _Nullable target) {

    //... ...
    //return result;
}];

Default PathFunction 默认路径函数

name
--------------------
@nslog
@isNSNull
@isAllEqual
@isAllDifferent
--------------------

Default behavior

  • 当调用未注册的方法时,函数名称作为选择器名称调用。如果有返回值则返回,没有返回值则返回目标本身。
id viewThatRemoved = [... akvc_valueForExtensionPath:@"view.@removeFromSuperview"];
  • 可以使用带有参数的方法,但不推荐。所有参数都使用默认值。
id mulArraySelf = [mulArray akvc_valueForExtensionPath:@"@removeObjectAtIndex:.@removeObjectAtIndex:"];

Equivalent ==> 

[mulArray removeObjectAtIndex:0];
[mulArray removeObjectAtIndex:0];
id mulArraySelf = mulArray;

Subkey

属性键的子字符串。

  • 表达式:<...>
`time` can match 'createTime' and 'modifyTime'.

[... akvc_valueForExtensionPath:@"...<time>.@isAllEqual"];

Regkey

属性键表达式。

  • 表达式:<$...$>
`button\\d+` can match 'button0','button1', ...

[... akvc_setValue:@(YES) forExtensionPath:@"...<button\\d+>.hidden"];

SELInspector

如果 iSELInspector 是最后一个组件,则等于 - respondsToSelector: .

  • 表达式:SEL(...)?
NSNumber *value = [... akvc_valueForExtensionPath:@"...SEL(addObject:)?"];

如果 SELInspector 不是最后一个组件,它是执行下一个路径的条件。

[... akvc_setValue:@"Trump" forExtensionPath:@"...friend.SEL(setNickName:)?.nickName"];

ClassInspector

如果 ClassInspector 是最后一个组件,则等同于 isKindOfClass: .

  • 表达式:Class(...)?
[... akvc_valueForExtensionPath:@"...Class(NSArray)?"];

如果 ClassInspector 不是最后一个组件,则它是一个执行下一路径的条件。

[... akvc_setValue:@"Trump" forExtensionPath:@"...friend.Class(AkvcPerson)?.nickName"];

KeysAccessor

使用 KeysAccessor 同时访问多个路径。返回的结果按顺序放置在数组中。多键访问,返回按顺的数组

  • 讨论:在 KeysAccessor 中,谓词(Predicate)、子键(Subkey)、注册键(Regkey)被禁用!此外,nil 值将被替换为 NSNull。
  • 表达式:{...}
[... akvc_valueForExtensionPath:@"{Breakfast.name, lunch.name, dinner.name}.@isAllEqual"];

PredicateFilter

PredicateFilter 等同于 - filteredArrayUsingPredicate

  • 表达式:@:PredicateString!
  • 讨论:符号 !.?. 禁止使用,但 ?!. 可用。
[... akvc_valueForExtensionPath:@"...users.@:age>18 && sex == 0!"];

在 ExtensionPath 中使用占位符用于谓词组件

  • 讨论:参数列表仅接受装箱值。使用 AkvcBoxValue(...) 来包装标量。只接受装箱参数
[... akvc_valueForExtensionPathWithPredicateFormat:@"...@:@K == %@!...@:SELF == %@?", object0, object1, object2];

PredicateEvaluate

PredicateEvaluate 等价于 - evaluateWithObject: . 参考 PredicateFilter

  • 表达式:@:PredicateString?

组件 ...?

  • Class(...)?(ClassInspector), SEL(...)?(SELInspector),@:...? (PredicateEvaluate)
    - 所有这些组件都有这个特性:如果不是最后一个组件,它将作为是否执行下一个路径的条件。当为 false 时返回 nil 或不执行任何操作,否则执行下一个路径。
    • 在路径中时这类组件表示是否执行的条件,当为 false 时返回 nil 或者什么也不做,当为 true 时执行后面。

注册自定义结构体

  • 注册自定义结构体需要两个方法: + registStruct:getterMap:+ registStruct:setterMap:
    • getter 映射表或setter映射表的键是结构的成员名
    • getter映射表的值是一个类似 __kindof NSValue*(^GetBlockType)(NSValue* value) 的块
@{
    @"size"   :   ^(NSValue* value){
    
        return [NSValue valueWithCGSize:[value CGRectValue].size];
    } ,
    ... ...
}
  • setter映射表的值是一个类似 __kindof NSValue*(^SetBlockType)(NSValue* value , id newValue) 的块
@{
    @"size"   :   ^(NSValue* value , id newValue){

        CGRect rect = [value CGRectValue];
        rect.size = [newValue CGSizeValue];
        return [NSValue valueWithCGRect:rect];
    } ,
    ... ...
}

清除缓存

[AkvcExtension cleanCache];

链式编程

  • NSObject+AkvcExtensionChain.h 定义了链式编程的API。所有setter的返回值都是目标本身。
_NonnullObject.akvcSetValueForExtensionPath(...)akvcSetValueForExtensionPath(...)...

作者