zl程序教程

您现在的位置是:首页 >  其它

当前栏目

没想到Swift里KVC还能有坑

swift 没想到 KVC
2023-09-27 14:20:49 时间

起因

最近看了@南峰子_老驴写的ViewStyle。利用KVC的来简化抽取出控件设置style的代码,想达到一个css的效果。这个库用swift编写,使用起来大概这样:


class ViewController: UIViewController {      var tableView: UITableView?      override func viewDidLoad() {          super.viewDidLoad()          tableView = UITableView(frame: self.view.bounds)          tableView!.mi_styles = self.tableViewStyle          self.view.addSubview(tableView!)      }  // MARK: - Table View Style  extension ViewController {      var tableViewStyle: [Property: Any] {          return [              .rowHeight: 60.0,              .separatorStyle: UITableViewCellSeparatorStyle.singleLine,              .separatorColor: UIColor.lightGray,              .backgroundView: UIView(),              .separatorInset: UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0),              .cellLayoutMarginsFollowReadableWidth: true          ]      } 

阅读源码后发现有些属性在swift是不能直接KVC的,和OC有些区别。

Bool值:isHidden

先来看下正常的在swift中kvc的套路:


let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))  view.setValue(UIColor.blue, forKey: #keyPath(UIView.backgroundColor))  

在swift 3中提供了#keypath()来省去开发者直接输入字符串的尴尬。

然而,如果这个属性是isHidden的话运行起来就会报错。

控制台会输出错误:


‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key isHidden.’ 

提示我们没有isHidden这个属性。

那为什么我们平时没有注意到这个问题呢?


view.isHidden = true 

这么写代码是没问题的。

其实就是Swift团队在升级3.0的时候keypath忘记做这个功能了。。。

你可以安慰自己这个功能在swift 2.0的时候还是好好的。

如果读者写过OC这个原因很容易猜到。有些单独声明过getter的bool值直接kvc会报错。比如isHidden这样:


@property (nonatomic, getter=isHidden) BOOL hidden; 

UIView上确实没有isHidden属性,那么怎么解决呢?只能回到老路上了:


view.setValue(true, forKey: "Hidden") 

Enum

KVC在设置枚举的时候也会报错。

错误提示的无效的参数类型。

因为setValue的参数类型是Any,所以这里参数可以是任意类型,没有类型检查。但是这毕竟是一个OC的方法,所以无法直接使用swift的类型(其实String到NSString也是有转换的,只是编译器帮我们做了这层转换)。

前面直接赋值的时候是正常的,但是调用KVC方法的时候编译器没有帮我们转。所以这里报错了。

那就只能自己手动转换了:


view.setValue(UIViewTintAdjustmentMode.automatic.rawValue, forKey: "tintAdjustmentMode") 

在OC中的枚举其实就是对应几个数值,这里直接取出rawValue的值就可以正常使用了。

最后我有一句话想对swift说:


本文作者:佚名 来源:51CTO
Swift是什么意思? Swift是一种新的编程语言,用于编写iOS和macOS应用。Swift结合了C和Objective-C的优点并且不受C兼容性的限制。Swift采用安全的编程模式并添加了很多新特性,这将使编程更简单,更灵活,也更有趣。
Swift实用小册15:OptionalChaining可选链的使用 可选链,是一种以安全的方式访问类的对象属性的方式。 可选链的作用,其实是为了在我们访问某个对象属性时,防止由于返回结果为nil,即属性不存在而引发的系统报错或者闪退,因为Swift不能空调用。
Swift实用小册14:Destructor析构函数的使用 析构函数,也叫析构器。 它是在对象销毁的时候自动调用,完成实例清理工作以释放资源的函数。 在Swift语言中,我们使用Initializer构造函数,在实例初始化时调用,以实现初始化的业务场景。
第一个受到关注的Swift应用?“Flappy Swift”分享与简析 距离苹果公司刚刚在WWDC 2014上,发布新一代苹果平台编程语言Swift刚刚过去个11小时,开发者Nate Murray就放出了基于测试版Swift开发的应用——一个重制Flappy Bird的简易原型。
Swift虽然推荐面向协议编程,但其也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象(类的实例) Swift中用class关键字定义类 class 类名 { // 定义属性和方法
Swift 语言由苹果公司在 2014 年推出,用来撰写 Mac OS 和 iOS 应用程序 Apple WWDC 2014 横空出世