如果类型是集合

时间:2015-06-13 10:40:07

标签: ios swift

我正忙着写一个递归方法。没有明确的“子”,只有集合,所以我想检查一下是否可以迭代一些属性。

我看到人们找到Swift.Array<String>,但这只会增加我需要测试的类型数量。

我应该尝试演员然后获得点数吗?

class ChildArray : NSArray {
}

3 个答案:

答案 0 :(得分:0)

您可以利用Swift和Objective-C之间的免费桥接。 ObjC中的对象有一个isKindOfClass方法来识别它们是否来自一个类:

class ChildArray : NSArray {
}

func isCollectionType(value : AnyObject) -> Bool {
    let object = value as! NSObject

    return object.isKindOfClass(NSArray)
}

var arrayOfInt = [1, 2, 3]
var myArray = ChildArray()
var anInt = 42

println(isCollectionType(arrayOfInt)) // true
println(isCollectionType(myArray))    // true
println(isCollectionType(anInt))      // false

答案 1 :(得分:0)

检查对象是否实现协议通常很简单。

if let _ = myArray as? CollectionType {        
}

但是这会因编译错误而失败。

error: protocol 'CollectionType' can only be used as a generic constraint because it has Self or associated type requirements

使用Objective-C运行时也是不可能的,因为这是一个纯粹的Swift协议。你必须使用反射来测试它。

var myArray :AnyObject = [1,2]

let reflectedArray = Mirror(reflecting: myArray)
if reflectedArray.displayStyle == .Some(.Collection){
    print("is collection")
}

答案 2 :(得分:0)

如果我们需要ArrayDictionarySet(列表可以更新),那么通过解析对象类型可以非常直接地完成任务:< / p>

func isCollection<T>(_ object: T) -> Bool {
    let collectionsTypes = ["Set", "Array", "Dictionary"]
    let typeString = String(describing: type(of: object))

    for type in collectionsTypes {
        if typeString.contains(type) { return true }
    }
    return false
}

用法:

var set : Set! = Set<String>()
var dictionary : [String:String]! = ["key" : "value"]
var array = ["a", "b"]
var int = 3
isCollection(int) // false
isCollection(set) // true
isCollection(array) // true
isCollection(dictionary) // true

硬编码是缺点,但它确实起到了作用。