Swift:为类类型过滤NSSet

时间:2022-09-27 23:24:58

In objective-C I had this function to filter an NSSet for an array of class types:

在objective-C中,我有这个函数来过滤一个类类型数组的NSSet:

+ (NSSet *)filterSubjectsSet:(NSSet *)subjects forClasses:(NSArray *)classes
{
    NSSet *filterSet = [subjects objectsPassingTest:^(id obj, BOOL *stop) {
        return [classes containsObject:[obj class]];
    }];
    return filterSet;
}

I am struggling to find a neat way to implement the same function in Swift. This is what I had hoped would work:

我正在努力寻找一种在Swift中实现相同功能的巧妙方法。这是我希望的工作方式:

class func filterSubjectsSet(subjects: NSSet, forClasses classes: [AnyClass]) -> NSSet {

    let set = subjects.objectsPassingTest() {
        find(classes, object_getClass($0)) != nil
    }        
    return set
}

But I get this error:

但我得到这个错误:

Type 'AnyObject.Type' does not conform to protocol 'Equatable'

How should I be doing this?

我该怎么做?

1 个解决方案

#1


1  

The find() function is specified as:

find()函数指定为:

func find<C : Collection where C.GeneratorType.Element : Equatable>
   (domain: C, value: C.GeneratorType.Element) -> C.IndexType?

and thus the collection, classes in your case, must be Equatable. Apparently a class type is not equatable - hence the error. I'd just loop over the classes 'by hand' as:

因此,您的案例中的集合类必须是Equatable。显然类类型不是等同的 - 因此错误。我只是手动循环上课:

{
  let set = subjects.objectsPassingTest() {
    for class in classes {
      if class === object_getClass($0) {
        return true
      }
    return false
  }
  return set
}

Putting it all together into an example with a slight rewrite of the above body:

将所有内容组合成一个示例,稍微重写上述正文:

  1> import Cocoa 
  2. class Foo { init () {} } 
  3. class Bar : Foo { init () { super.init()} } 
  4. class Bing { init () {} } 
  5.  
  6. let b1 = Bing() 
  7. let b2 = Bing() 
  8.  
  9. var set1 = NSMutableSet() 
 10. set1.addObject(b1) 
 11. set1.addObject(b2) 
 12.  
 13. func filterSubjectsSet (subjects: NSSet, forClasses classes: [AnyClass]) -> NSSet { 
 14.   return subjects.objectsPassingTest() { 
 15.     (obj: AnyObject!, boolPtr: UnsafePointer<ObjCBool>) in 
 16.     for nextClass in classes { 
 17.       if nextClass === object_getClass(obj) { 
 18.         return true 
 19.       } 
 20.     } 
 21.     return false 
 22.   } 
 23. } 
 24.  
 25. set1.count 
 26.  
 27. filterSubjectsSet (set1, forClasses: [object_getClass(b1)]).count
$R0: Int = 2
b1: __lldb_expr_1.Bing = {}
b2: __lldb_expr_1.Bing = {}
set1: __NSSetM = 2 objects {
  [0] =
  [1] =
}

#1


1  

The find() function is specified as:

find()函数指定为:

func find<C : Collection where C.GeneratorType.Element : Equatable>
   (domain: C, value: C.GeneratorType.Element) -> C.IndexType?

and thus the collection, classes in your case, must be Equatable. Apparently a class type is not equatable - hence the error. I'd just loop over the classes 'by hand' as:

因此,您的案例中的集合类必须是Equatable。显然类类型不是等同的 - 因此错误。我只是手动循环上课:

{
  let set = subjects.objectsPassingTest() {
    for class in classes {
      if class === object_getClass($0) {
        return true
      }
    return false
  }
  return set
}

Putting it all together into an example with a slight rewrite of the above body:

将所有内容组合成一个示例,稍微重写上述正文:

  1> import Cocoa 
  2. class Foo { init () {} } 
  3. class Bar : Foo { init () { super.init()} } 
  4. class Bing { init () {} } 
  5.  
  6. let b1 = Bing() 
  7. let b2 = Bing() 
  8.  
  9. var set1 = NSMutableSet() 
 10. set1.addObject(b1) 
 11. set1.addObject(b2) 
 12.  
 13. func filterSubjectsSet (subjects: NSSet, forClasses classes: [AnyClass]) -> NSSet { 
 14.   return subjects.objectsPassingTest() { 
 15.     (obj: AnyObject!, boolPtr: UnsafePointer<ObjCBool>) in 
 16.     for nextClass in classes { 
 17.       if nextClass === object_getClass(obj) { 
 18.         return true 
 19.       } 
 20.     } 
 21.     return false 
 22.   } 
 23. } 
 24.  
 25. set1.count 
 26.  
 27. filterSubjectsSet (set1, forClasses: [object_getClass(b1)]).count
$R0: Int = 2
b1: __lldb_expr_1.Bing = {}
b2: __lldb_expr_1.Bing = {}
set1: __NSSetM = 2 objects {
  [0] =
  [1] =
}