问题:
1.控制台要po某个变量(尤其是字典的键值)时出现 <extracting data from value failed>
2.KVO监听BOOL类型的时候出现BUG
原因:
总体来说就是因为KVO的change字典存的不是官方公开的类型,而是一些私有的(前面带下划线的)类型,用的时候要处理一下,比如BOOL就要注意一点(例子2)
-
情况1:
该变量不能在控制台打印输出,但是程序跑起来没毛病
比如我这个例子中,要在控制台 po 的东西其实是个NSURL,正常情况下是可以在控制台po出来的。
但如果 这个NSURL是存在字典中(比如KVO的change字典)这时候在控制台po就会出现取不到value -- <extracting data from value failed>
比如,在使用KVO监听webView的URL属性时,URL发生变化了
此时通过KVO回调方法observeValueForKeyPath:...
里面的change
去取这个新的值--change[NSKeyValueChangeNewKey]
此时打断点,在控制台打印就是
<extracting data from value failed>
但结果还是能正常使用这个NSURL的,只是控制台不能po出来
//下面这个是给我自己做个记录,免得以后再犯这个错
在我的程序中如果直接让它跑过去会报错:
-[NSURL rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x6000002e0b80
显然是因为我没有意识到KVO的change中取出来的是一个NSURL,我还傻乎乎地把它放给textField去用
解决方法就是用NSURL *urlTemp=change[NSKeyValueChangeNewKey]
去接到这个值然后用XXtextField.text = urlTemp.absoluteString
来赋值。
-
情况2:
不仅不能在控制台打印输出,程序也有 !!BUG!!
这个出现在我监听BOOL类型的时候,当时的情况大概就是不管我的BOOL是什么,KVO的change字典中得到玩意赋出来都是YES
原因是:
KVO中change字典里面存的不是BOOL
而是__NSCFBoolean
这玩意除了不能在控制台打印出来,还有个麻烦--它是个结构体,结果就是不管监听的BOOL变量A是YES还是NO,到这里都是一个枚举类型。(kCFBooleanFalse
和kCFBooleanTrue
)
如果直接把这个枚举类型拿去赋值给一个新的BOOL变量B,肯定一直都是有值不是nil或者null,所以这个新的BOOL变量B就会一直是YES。 -
解决办法:
step1:用CFBooleanRef temp = (__bridge CFBooleanRef)([change allValues][1]);
接收
step2:三目赋值self.functionView.leftBtn.enabled = (temp == kCFBooleanFalse)?NO:YES;