频道栏目
首页 > 资讯 > IOS > 正文

ios开发学习之kvc的使用解析

18-07-21        来源:[db:作者]  
收藏   我要投稿

ios开发学习之kvc的使用解析

整个过程:

证明第一步,走set和_set方法:

@interface Person : NSObject

@end

#import "Person.h"

@implementation Person

- (void)setAge:(NSString *)age
{
 NSLog(@"_setAge");
}

//- (void)_setAge:(NSString *)age
//{
  //  NSLog(@"_setAge");
//}

@end
 self.person = [[Person alloc] init];

 NSKeyValueObservingOptions optips = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
 [self.person addObserver:self forKeyPath:@"age" options:optips context:@"sdf"];

 [self.person setValue:@10 forKey:@"age"];


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
 NSLog(@"监听到%@的%@属性发生了变化-%@ -%@",object, keyPath, change, context);
}
结果:
当实现setAge时 就会打印:
2018-07-18 23:18:23.984 newxc[5009:1640392] setAge
当实现_setAge时,就会打印
2018-07-18 23:18:23.984 newxc[5009:1640392] _setAge
第二步:
不实现setAge 和_setAge


#import "Person.h"

@implementation Person

+ (BOOL)accessInstanceVariablesDirectly
{
 return NO;  // 不允许访问成员变量
}
结果:
会报错:
2018-07-18 23:20:35.584 newxc[5060:1644779] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key age.'
*** First throw call stack:
(
	0CoreFoundation 0x000000010aeceb0b __exceptionPreprocess + 171
	1libobjc.A.dylib0x000000010a933141 objc_exception_throw + 48
	2CoreFoundation 0x000000010aecea59 -[NSException raise] + 9
	3Foundation  0x000000010a511731 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
	4Foundation  0x000000010a440e1d -[NSObject(NSKeyValueCoding) valueForKey:] + 284
	5Foundation  0x000000010a43bb44 NSKeyValueWillChangeBySetting + 60
	6Foundation  0x000000010a436057 NSKeyValueWillChange + 414
	7Foundation  0x000000010a40c603 -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] + 477
	8Foundation  0x000000010a51704b _NSSetValueAndNotifyForUndefinedKey + 45
	9Foundation  0x000000010a448e8b -[NSObject(NSKeyValueCoding) setValue:forKey:] + 292
	10  newxc 0x000000010a36316c -[ViewController viewDidLoad] + 476
	11  UIKit 0x000000010b494cca -[UIViewController loadViewIfRequired] + 1235
	12  UIKit 0x000000010b49510a -[UIViewController view] + 27
	13  UIKit 0x000000010b35d63a -[UIWindow addRootViewControllerViewIfPossible] + 65
	14  UIKit 0x000000010b35dd20 -[UIWindow _setHidden:forced:] + 294
	15  UIKit 0x000000010b370b6e -[UIWindow makeKeyAndVisible] + 42
	16  UIKit 0x000000010b2ea31f -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
	17  UIKit 0x000000010b2f0584 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
	18  UIKit 0x000000010b2ed793 -[UIApplication workspaceDidEndTransaction:] + 182
	19  FrontBoardServices0x000000010e54b5f6 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
	20  FrontBoardServices0x000000010e54b46d -[FBSSerialQueue _performNext] + 186
	21  FrontBoardServices0x000000010e54b7f6 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
	22  CoreFoundation 0x000000010ae74c01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
	23  CoreFoundation 0x000000010ae5a0cf __CFRunLoopDoSources0 + 527
	24  CoreFoundation 0x000000010ae595ff __CFRunLoopRun + 911
	25  CoreFoundation 0x000000010ae59016 CFRunLoopRunSpecific + 406
	26  UIKit 0x000000010b2ec02f -[UIApplication _run] + 468
	27  UIKit 0x000000010b2f20d4 UIApplicationMain + 159
	28  newxc 0x000000010a36381f main + 111
	29  libdyld.dylib  0x000000010ddd665d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 
但是 如果返回的是YES

+ (BOOL)accessInstanceVariablesDirectly
{
 return YES; // 允许访问成员变量。
}
这里需要注意一下,这里依然会监听,可能是内部实现了kvo必须实现的那两个方法。
2018-07-18 23:22:18.703 newxc[5079:1647618] 监听到的age属性发生了变化-{
 kind = 1;
 new = 10;
 old = 0;
} -sdf

这个赋值的属性请看下面

上面是kvo实现逻辑的验证过程。

这个是forKey和ForKeyPath的解释:

#import 

@interface Cat : NSObject

@property (nonatomic, strong) NSString *wight;


@end


@interface Person : NSObject

@property (nonatomic, strong) NSString *age;

@property (nonatomic, strong) Cat *cat;


@end
 [self.person setValue:@10 forKey:@"age"]; // key只能访问简单的属性
 [self.person setValue:@10 forKeyPath:@"cat.wight"]; // 这个可以一层一层访问

1:通过kvc修改属性会触发kvo么?

会触发

原理:

2:kvc的赋值和取值过程是怎样的?原理是什么?

相关TAG标签
上一篇:Goldbach's Conjecture 解析
下一篇:Linux系统下软连接和硬链接的区别
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站