KeyPathExtension
-
An extension of KeyPath in KVC for objc runtime.
-
Describe complex logic with less code in KeyPath.Reduce programmer doing work.
- Access structural value in the KeyPath.
- Using Predicate in the KeyPath
- Implementing custom function or @NSKeyValueOperator(@avg, @count, ...).
- Perform type-safe checks directly in the KeyPath.
- One start, more length.
-
用较少的代码描述复杂的逻辑,减少做功
- 在KVC中直接访问结构体成员
- 在KVC中使用谓词
- 实现自定义函数或@NSKeyValueOperator(@avg, @count, ...)
- 在KVC中直接进行类型安全的检查
- 随手一赞,好运百万
-
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
- Emergency: [email protected]