KeyPathExtension 1.0.6

KeyPathExtension 1.0.6

Maintained by Novo.



  • By
  • Meterwhite

LogoKeyPathExtension

  • An extension of KeyPath in KVC for objc runtime.

  • Describe complex logic with less code in KeyPath.Reduce programmer doing work.

    1. Access structural value in the KeyPath.
    2. Using Predicate in the KeyPath
    3. Implementing custom function or @NSKeyValueOperator(@avg, @count, ...).
    4. Perform type-safe checks directly in the KeyPath.
    5. One start, more length.
  • 用较少的代码描述复杂的逻辑,减少做功

    1. 在KVC中直接访问结构体成员
    2. 在KVC中使用谓词
    3. 实现自定义函数或@NSKeyValueOperator(@avg, @count, ...)
    4. 在KVC中直接进行类型安全的检查
    5. 随手一赞,好运百万
  • Key words : KeyPath Extension KVC Extension sort in key path

Import

  • Drag all source files under folder KeyPathExtension to your project.
#import "KeyPathExtension.h"
  • Or use CocoaPods.
pod 'KeyPathExtension'
  • iOS & macOS

Overview

Examples

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

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

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

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

///Get the path in a different way.
@akvcGetPath(object, a.b.c.d).akvcPathAppend(@"e.f.g.h").akvcPathAppendCode(h.i.j.k);

Content


ExtensionPath

All features

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

StructPath

StructPath can access the structure.

  • Accessing properties in a structure using the accessor ->.结构体访问符
@"...NSKeyPath->StructKey->StructKey";

Indexer

Provides a simple way to access array elements in key path.

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 is a custom NSKeyValueOperator.自定义路径函数

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

Regist PathFunction

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

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

Default PathFunction 默认路径函数

name
--------------------
@nslog
@isNSNull
@isAllEqual
@lastObject
@firstObject
@isAllDifferent
--------------------

Default behavior

  • When an unregistered method is called, the function name is called as selector name. Returns if there is a return value, if no returns the target itself.
id viewThatRemoved = [... kpe_valueForExtensionPath:@"view.@removeFromSuperview"];
  • It is legal to use a method with parameters, but it is not recommended. All parameters are the default values.
id mulArraySelf = [mulArray kpe_valueForExtensionPath:@"@removeObjectAtIndex:.@removeObjectAtIndex:"];

Equivalent ==> 

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

Subkey

Sub string of property key.

  • Expressions :<...>
`time` can match 'createTime' and 'modifyTime'.

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

Regkey

Expressions of property key.

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

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

SELInspector

If iSELInspector is the last component, it is equivalent to - respondsToSelector: .

  • Expressions :SEL(...)?
NSNumber *value = [... kpe_valueForExtensionPath:@"...SEL(addObject:)?"];

If SELInspector is not the last component, it is a condition for whether execute next path.

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

ClassInspector

If ClassInspector is the last component, it is equivalent to isKindOfClass: .

  • Expressions :Class(...)?
[... kpe_valueForExtensionPath:@"...Class(NSArray)?"];

If ClassInspector is not the last component, it is a condition for whether execute next path.

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

KeysAccessor

Use Keysaccessor to access multiple paths at once.The returned results are placed sequentially in the array.多键访问,返回按顺的数组

  • Discussion : Predicate, Subkey, Regkey are disable in KeysAccessor!In addition,and the nil value will be replaced by NSNull.
  • Expressions :{...}
[... kpe_valueForExtensionPath:@"{Breakfast.name, lunch.name, dinner.name}.@isAllEqual"];

PredicateFilter

PredicateFilter equates to - filteredArrayUsingPredicate:

  • Expressions :@:PredicateString!
  • Discussion : Symbol !. or ?. is forbidden to use, but ?, ! , . are available.
[... kpe_valueForExtensionPath:@"...users.@:age>18 && sex == 0!"];

Use placeholders in ExtensionPath for predicate component

  • Discussion : The parameter list accepts only boxed values.Use AkvcBoxValue(...) to wrap scalar.只接受装箱参数
[... kpe_valueForExtensionPathWithPredicateFormat:@"...@:@K == %@!...@:SELF == %@?", object0, object1, object2];

PredicateEvaluate

PredicateEvaluate equates to - evaluateWithObject: . Refert to PredicateFilter

  • Expressions :@:PredicateString?

Component ...?

  • Class(...)?(ClassInspector), SEL(...)?(SELInspector),@:...? (PredicateEvaluate)
    -All this component has this feafure : If it's not the last component, it will as a condition for whether to execute next path.While false it return nil or do noting, else execute next path.
    • 在路径中时这类组件表示是否执行的条件,false时返回nil或者什么也不做,true时执行之后。

Regist custom struct

  • Register a custom struct need 2 method : + registStruct:getterMap: and + registStruct:setterMap:
    • Key of getter map or setter map is member name of structural
    • Value of getter map is a block like __kindof NSValue*(^GetBlockType)(NSValue* value)
@{
    @"size"   :   ^(NSValue* value){
    
        return [NSValue valueWithCGSize:[value CGRectValue].size];
    } ,
    ... ...
}
  • Value of setter map is a block like __kindof NSValue*(^SetBlockType)(NSValue* value , id newValue)
@{
    @"size"   :   ^(NSValue* value , id newValue){

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

Clean cache

[KeyPathExtension cleanCache];

Chain programming

  • NSObject+KeyPathExtensionChain.h defines the API for chained programming.The return value of all setter is target itself.
_NonnullObject.akvcSetValueForExtensionPath(...)akvcSetValueForExtensionPath(...)...

Need expand KeyPathExtension