iOS 개발 KVC
11289 단어 총결산
iOS 개발 KVC
KVC 소개:
KVC(key-value codeing)는 애플이 제공하는 실행 시 기반 인코딩 기술이다.이것은 개발자가 키 값을 통해 대상에 대응하는 속성에 직접 접근할 수 있도록 하고 set, get 방법을 명확하게 호출할 필요가 없기 때문에 kvc는 실행할 때 동적으로 대상의 속성을 수정할 수 있다. 이것도 그의 강점이다.대상이 속성을 실현하는 set, get 방법이 없다면, 그 속성 값을 kvc로 직접 저장할 수 있습니다. 이 변수가 클래스 인터페이스에서 정의되었든, 클래스에서 정의되었든, 어떤 접근 수식자를 사용했든, 이름으로만 존재하는 변수든, KVC는 이 구성원 변수에 값을 부여할 수 있습니다.만약에 속성이 set, get 방법을 실현한다면 가능한 set, get 방법을 통해 값을 저장해야 코드의 봉인성을 파괴하지 않고 안전하고 효율적이다.KVC의 정의는 모두 NSObject의 확장에서 이루어진 것이다. (NSKeyValueCodeing 클래스)그래서 NSObject의 대상을 계승해야만 KVC를 사용할 수 있고 일부 순수한 swift류의 구조체는 KVC를 사용할 수 없다.
KVC에서 주로 사용하는 몇 가지 방법은 다음과 같습니다.
NSArray *array = @[@3, @6, @7, @8, @10];
//
NSNumber *sum = [array valueForKeyPath:@"@sum.self"];
//
NSNumber *avg = [array valueForKeyPath:@"@avg.self"];
//
NSNumber *max = [array valueForKeyPath:@"@max.self"];
//
NSNumber *min = [array valueForKeyPath:@"@min.self"];
//
NSNumber *sum = [array valueForKeyPath:@"@sum.floatValue"];
NSNumber *avg = [array valueForKeyPath:@"@avg.floatValue"];
NSNumber *max = [array valueForKeyPath:@"@max.floatValue"];
NSNumber *min = [array valueForKeyPath:@"@min.floatValue"];
// :@distinctUnionOfObjects @unionOfObjects
NSArray * txArr = @[@"aa", @"bb",@"cc",@"aa", @"cc"];
NSLog(@"txArr : %@", [txArr valueForKeyPath:@"@distinctUnionOfObjects.self"]);
// : name name
NSArray * dicArr = @[@{@"zhang":@"wang", @"age":@12, @"gender":@"man"},
@{@"name":@"zhang", @"age":@12, @"gender":@"woman"},
@{@"name":@"li", @"age":@12, @"gender":@"man"}];
NSLog(@"txArr : %@", [txArr valueForKeyPath:@"@distinctUnionOfObjects.name"]);
// uitextFile placeholder
[searchField setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
KVC의 몇 가지 중요한 방법:참고: setObject: forKey: NSMutable Dictionary 고유의 방법입니다.value는nil/null일 수 없지만 [NSNull null](객체 유형이기 때문에)일 수 있으며 반드시 객체여야 합니다.
다음은 장면의 예입니다.
4
// Cameras.h
#import
#import "NiCon.h"
NS_ASSUME_NONNULL_BEGIN
@interface Cameras : NSObject
@property(nonatomic,strong)NiCon * nicon1;
@end
NS_ASSUME_NONNULL_END
//Cameras.m
#import "Cameras.h"
@interface Cameras()
@property(nonatomic,strong)NiCon * nicon2;
@end
@implementation Cameras
// nicon1 set、get ;
@synthesize nicon1;
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
- (id)valueForUndefinedKey:(NSString *)key{
NSLog(@" key: %@ ", key);
return nil;
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@" key : %@ ", key);
}
+(BOOL)accessInstanceVariablesDirectly{
// return NO;
// 2019-03-11 16:49:44.899991+0800 test[2256:72136] key : nicon1
// 2019-03-11 16:49:44.900311+0800 test[2256:72136] nicon1: (null)
return YES;
// 2019-03-11 16:44:29.408502+0800 test[2112:64508] nicon1:
// 2019-03-11 16:44:29.408724+0800 test[2112:64508] nicon2:
// 2019-03-11 16:44:29.409306+0800 test[2112:64508] nicon1.devName: X525
// 2019-03-11 16:44:29.409462+0800 test[2112:64508] nicon2.devName: X525
}
@end
두 번째 클래스://NiCon.h
#import
NS_ASSUME_NONNULL_BEGIN
@interface NiCon : NSObject
@property(nonatomic, copy)NSString * devName;
@end
NS_ASSUME_NONNULL_END
//NiCon.m
#import "NiCon.h"
@interface NiCon()
@property(nonatomic,assign) int devNO;
@end
@implementation NiCon
-(BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable __autoreleasing *)outError{
return [inKey isEqualToString:@"devNO"];
}
@end
그런 다음 view Controller에서 KVC를 사용하여 객체의 속성에 값을 지정합니다.//viewController.m
- (void)viewDidLoad {
[super viewDidLoad];
Cameras* cams = [[Cameras alloc]init];
NiCon * nic1 = [[NiCon alloc]init];
//
[cams setValue:nic1 forKey:@"nicon1"];
NSLog(@"nicon1: %@", cams.nicon1);
// 2019-03-11 16:06:01.305184+0800 test[876:12560] nicon1:
//
[cams setValue:nic1 forKey:@"nicon2"];
NSLog(@"nicon2: %@", [cams valueForKey:@"nicon2"]);
// 2019-03-11 16:09:26.472743+0800 test[999:20027] nicon2:
}
상기 예시에서 알 수 있듯이 공유 속성이든 개인 속성이든 KVC는 모두 성공적으로 값을 부여하고 값을 얻을 수 있기 때문에 KVC는 액세스 수식자의 제한을 받지 않는다.다음은 Cameras의 속성 nicon1의 속성 이름을 로 변경합니다.nicon1, isNicon1, 그리고 +(BOOL)accessInstanceVariablesDirectly 반환값을 각각 YES와 NO로 설정하여 값을 부여할 수 있는지 확인합니까?
//Cameras.h
//@property(nonatomic,strong)NiCon * _nicon1;
//@property(nonatomic,strong)NiCon * isNicon1;
//NiCon.m
// Key , , , 。
- (id)valueForUndefinedKey:(NSString *)key{
NSLog(@" key: %@ ", key);
return nil;
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
NSLog(@" key : %@ ", key);
}
+(BOOL)accessInstanceVariablesDirectly{
// return NO;
return YES;
- (void)viewDidLoad {
[super viewDidLoad];
Cameras* cams = [[Cameras alloc]init];
NiCon * nic1 = [[NiCon alloc]init];
//
[cams setValue:nic1 forKey:@"nicon1"];
NSLog(@"nicon1: %@", cams._nicon1);
// return NO;
// 2019-03-11 16:49:44.899991+0800 test[2256:72136] key : nicon1
// 2019-03-11 16:49:44.900311+0800 test[2256:72136] nicon1: (null)
// return YES;
// 2019-03-11 16:44:29.408502+0800 test[2112:64508] nicon1:
// 2019-03-11 16:44:29.408724+0800 test[2112:64508] nicon2:
//
[cams setValue:nic1 forKey:@"nicon1"];
NSLog(@"nicon1: %@", cams.isNicon1);
// return NO;
// 2019-03-11 16:49:44.899991+0800 test[2256:72136] key : nicon1
// 2019-03-11 16:49:44.900311+0800 test[2256:72136] nicon1: (null)
// return YES;
// 2019-03-11 16:44:29.408502+0800 test[2112:64508] nicon1:
// 2019-03-11 16:44:29.408724+0800 test[2112:64508] nicon2:
}
이상의 테스트에서 +(BOOL)accessInstanceVariablesDirectly를 검증하였습니다.반환 값이 YES(기본값)로 설정되어 있으면 런타임 시 속성에 대한 Set 메서드를 찾을 수 없는 경우key,_iskey, key, iskey의 순서대로 구성원 변수를 검색합니다. NO로 설정하면 KVC 검색을 비활성화합니다. set을 찾지 못하면 get 방법은 이상을 던집니다.KVC의 setValue:forKeyPath:객체의 중첩 속성을 설정하려면 다음과 같이 하십시오.
- (void)viewDidLoad {
[super viewDidLoad];
Cameras* cams = [[Cameras alloc]init];
NiCon * nic1 = [[NiCon alloc]init];
// keyPath
[cams setValue:@" X525" forKeyPath:@"nicon1.devName"];
NSLog(@"nicon1.devName: %@", [cams valueForKeyPath:@"nicon1.devName"]);
// test[1380:36444] nicon1.devName: X525
// keyPath
[cams setValue:@" X525" forKeyPath:@"nicon2.devName"];
NSLog(@"nicon2.devName: %@", [cams valueForKeyPath:@"nicon2.devName"]);
// test[1540:43465] nicon2.devName: X525
이를 통해 알 수 있듯이 KVC는 공유와 사유의 플러그인 속성에 대해서도 두려워하지 않는다. 하하가 이렇게 강하다!KVC를 사용한 키 값 검증: - (BOOL)validateValue: (inout id nullable * nonnnull) ioValue forKey: (NSString *) inKey error: (out NSError **) outError;
//NiCon.m
@implementation NiCon
-(BOOL)validateValue:(inout id _Nullable __autoreleasing *)ioValue forKey:(NSString *)inKey error:(out NSError * _Nullable __autoreleasing *)outError{
return [inKey isEqualToString:@"devNO"];
}
//viewController.m
NSNumber * num = [NSNumber numberWithInteger:1011];
if ([cams validateValue:&num forKey:@"nicon2.devNO" error:nil]) {// KVC
[cams setValue:num forKeyPath:@"nicon2.devNO"];
NSLog(@"nicon2.devNO: %@", [cams valueForKeyPath:@"nicon2.devNO"]);
//log: test[6716:263169] nicon2.devNO: 1011
}
모델 및 사전 상호 전환: Cameras* cams = [[Cameras alloc]init];
//
NSArray * modelKeys = @[@"devName", @"devNO"];
NSDictionary * modelDic = [[cams valueForKey:@"nicon2"] dictionaryWithValuesForKeys:modelKeys]; NSLog(@"modelDic: %@", modelDic);
/* 2019-03-12 09:53:33.489429+0800 test[6716:263169] modelDic: {
devNO = 1011;
devName = "\U5c3c\U5eb7X525";
}
*/
//
NiCon * nicon3 = [[NiCon alloc]init];
[nicon3 setValuesForKeysWithDictionary:modelDic];
NSLog(@"devName: %@ devNO: %@",nicon3.devName, [nicon3 valueForKey:@"devNO"]);
// 2019-03-12 09:53:33.489696+0800 test[6716:263169] devName: X525 devNO: 1011
KVC는 확실히 강하지만 만사에 도가 있기 때문에 지나치면 안 된다. 그렇지 않으면 그 반대의 결과를 초래할 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
클릭 이벤트의 누적 귀속, 클릭 한 번, 여러 번 실행최근에 업무상 클릭 이벤트가 누적되는 문제에 부딪혔다. 요소에 클릭 이벤트 효과를 추가하지만 항상 효과가 실패한다. 마지막으로 클릭 이벤트가 여러 차례 실행된 것을 발견했다. 인터넷에서 찾아봤는데 다음은 이 문제를 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.