代码之家  ›  专栏  ›  技术社区  ›  Corey Floyd

是否可以按类筛选NSarray?

  •  23
  • Corey Floyd  · 技术社区  · 16 年前

    有没有方法构造一个谓词来按类类型过滤?

    我目前在数组中循环并检查每个对象的类。也许有更干净的方法?

    3 回复  |  直到 12 年前
        1
  •  22
  •   Dave DeLong    16 年前

    您可以向nsObject添加一个类别,该类别添加一个“cf_classname”方法,如下所示:

    @interface NSObject (CFAdditions)
    - (NSString *) cf_className;
    @end
    
    @implementation NSObject (CFAdditions)
    - (NSString *) cf_className {
      return NSStringFromClass([self class]);
    }
    @end
    

    从这里,您可以使用如下谓词:

    NSPredicate * p = [NSPredicate predicateWithFormat:@"cf_className = %@", aClass];
    NSArray * filtered = [anArray filteredArrayUsingPredicate:p];
    

    如果你在Mac上,你只需使用 -[NSObject className] 而不是必须创建类别。iPhone没有这种方法,因此需要一个类别。

        2
  •  73
  •   Ashley Clark    16 年前

    您也可以直接在谓词中比较类。

    但是,如果您试图筛选属于类集群的对象或者具有子类,那么它可能不会像您期望的那样工作。

    例如, NSDate 当实例化时通常是 __NSCFDate NSString 可以是 NSCFString 以及其他特定的私有类。

    最好是自己循环使用 -isKindOfClass: 作为测试。

    如果 真的? 想用 NSPredicate 尽管你能做到。作为一个例子,这将为派生自 非字符串 .如果你想要严格的班级成员资格,你可以替换 isKindOfClass: 具有 isMemberOfClass: .

    集合中所有对象实现的任何选择器,接受一个参数并返回 BOOL 不过应该管用。

    NSArray *mixedArray = {...};
    NSPredicate *predicate = [NSPredicate predicateWithFormat:
                                          @"self isKindOfClass: %@",
                                          [NSString class]];
    
    NSLog(@"%@", [mixedArray filteredArrayUsingPredicate:predicate]);
    
        3
  •  25
  •   Carl Veazey    12 年前

    从iOS 4和Mac OS 10.6开始,您可以使用 +[NSPredicate predicateWithBlock:] 也。例如:

    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
        return [object isKindOfClass:[NSString class]];
    }];
    

    这允许您纯粹用Objective-C来表示谓词,而不是 predicateWithFormat: .