【问题标题】:Swift: Filter a NSSet for class typesSwift:为类类型过滤 NSSet
【发布时间】:2014-07-25 11:10:39
【问题描述】:

在 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;
}

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

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

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

但我收到此错误:

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

我该怎么做?

【问题讨论】:

  • 你不应该测试一个对象是否是一个类(或其子类)的实例,而不是它的类正是那个类吗?

标签: cocoa swift nsset


【解决方案1】:

find() 函数指定为:

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

因此集合,在您的情况下为classes,必须是Equatable。显然一个类类型是不相等的——因此是错误的。我只是“手动”遍历类:

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

将所有内容放在一个示例中,并稍微重写上述主体:

  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] =
}

【讨论】:

  • 感谢@GoZoner。知道为什么这个函数调用失败并出现 EXC_BAD_INSTRUCTION 吗? let filtered = Subject.filterSubjectsSet(places, forClasses: [Hospital.self])
  • 我仍然收到 EXC_BAD_INSTRUCTION,在 Foundation._convertArrayToNSArray &lt;A&gt;(Swift.Array&lt;A&gt;) -&gt; ObjectiveC.NSArray 中提出。当我传递我的 forClasses 数组参数时,这似乎被调用了。我看不出我的代码与您上面的示例有任何区别。
猜你喜欢
  • 1970-01-01
  • 2017-12-08
  • 2022-12-06
  • 2019-06-03
  • 1970-01-01
  • 2014-12-01
  • 1970-01-01
相关资源
最近更新 更多