iOS开发 - NSPredicate试探(Swift5.1版)

最近看了一遍文章,是NSPredicate谓词的讲解。可是文章归文章,还是亲手试验一下才能转化成自己的知识。Let's go ~ !

  1. 如何理解NSPredicate的作用?
    根据它的语法,我简单粗暴地理解成它是一种 过滤条件 。 与SQL的查找语句比较相似

  2. 初试

由浅入深,先来写死参数试试
等价于 100 >= 167 <= 200 , 这个没问题。

iOS开发 - NSPredicate试探(Swift5.1版)_第1张图片
image

动态传参 ,使用字符串格式化占位符 %@ 、 %d ,这个也是很常用了。
但它并不检查语法,比如我尝试用Float类型传进去%d中,会出现类型不匹配,而导致条件语句并非我们所期望的

iOS开发 - NSPredicate试探(Swift5.1版)_第2张图片
image
iOS开发 - NSPredicate试探(Swift5.1版)_第3张图片
image
  1. 保留字(不论大小写)

AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE

  1. 数组过滤

(1) 首先抽出 BEGINSWITH (以特定条件开头)作为试验。网上看了很多文章,都是OC或者是旧版swift版本的。在swift5.1中,真实试验才发现有坑。

这是从网上文章参考的,定义了一个Person的类 , 类中带有name和age属性。一切看起来都完美无暇

class Person:NSObject {
    
    var name:String
    var age:Int
    init(name:String,age:Int) {
        self.name = name
        self.age = age
        super.init()
    }
    override var description:String{
        return "name:\(self.name) age:\(self.age)"
    }
}

(2) 然后添加三个数据,并开始过滤

let personArray = NSMutableArray.init()
        personArray.add(Person(name: "Jack Tomphon", age: 23))
        personArray.add(Person(name: "Mikle Steven", age: 25))
        personArray.add(Person(name: "Tacmk", age: 24))
        
        print("personArray-->\(personArray)")
        
        let predicate = NSPredicate.init(format: "%K BEGINSWITH %@", "name" , "M")

        print("条件语句-->\(predicate.predicateFormat)")
        
        let resultArray:NSArray = personArray.filtered(using: predicate) as NSArray
        
        print("结果-->\(resultArray)")

(3) 问题来了,报错 “该类与键名不符合键值编码” 。
这个问题困扰了一天,我尝试转用Swift的Array是没有NSPredicate的filter方法的。然后它的报错信息表明了,是使用KVC取值的,也就是基于runtime。再回想一下我们定义按钮点击方法时,函数名前面需要加上@objc,因为是动态发送消息。

iOS开发 - NSPredicate试探(Swift5.1版)_第4张图片
image.png

(4) 回到Person的属性上,试着加上@objc之后。成功得到期待中的结果了✌️


iOS开发 - NSPredicate试探(Swift5.1版)_第5张图片
image.png
  1. 特殊字符
 *     通配符 (配合LIKE作为模糊搜索使用)
?     代表一个字符 (配合LIKE作为模糊搜索使用)
  1. LIKE
    不配合*或? 的话,是精确匹配,必须完全相同才能拿到结果。

配合*通配符,下面例子是可以匹配到Mikle Steven。 如果通配符在后面,Steven* 则匹配不到

let personArray = NSMutableArray.init()
personArray.add(Person(name: "Jack Tomphon", age: 23))
personArray.add(Person(name: "Mikle Steven", age: 25))
personArray.add(Person(name: "Tacmk", age: 24))
let predicate = NSPredicate.init(format: "%K LIKE %@", "name" , "*Steven")
iOS开发 - NSPredicate试探(Swift5.1版)_第6张图片
image.png

配合?占位符,一个?占一个字符位置,长度不相同则匹配失败

let personArray = NSMutableArray.init()
personArray.add(Person(name: "Jack Tomphon", age: 23))
personArray.add(Person(name: "Mikle Steven", age: 25))
personArray.add(Person(name: "Tacmk", age: 24))
let predicate = NSPredicate.init(format: "%K LIKE %@", "name" , "??c??")
iOS开发 - NSPredicate试探(Swift5.1版)_第7张图片
image.png
  1. 忽略大小写[c] 与 忽略重音符号[d]
let personArray = NSMutableArray.init()
personArray.add(Person(name: "Jack Tomphon", age: 23))
personArray.add(Person(name: "Mikle Steven", age: 25))
personArray.add(Person(name: "Tacmk", age: 24))
personArray.add(Person(name: "ĨĢ", age: 100))

let predicate = NSPredicate.init(format: "%K LIKE[cd] %@", "name" , "*i*")
iOS开发 - NSPredicate试探(Swift5.1版)_第8张图片
image.png

虽然暂时没有在实际项目中使用过,但总感觉会用得上

小弟不才,若有错误之处,欢迎留言讨论(^_^)

你可能感兴趣的:(iOS开发 - NSPredicate试探(Swift5.1版))