我有一个由AnyObject
组成的数组。我想迭代它,找到所有数组实例的元素。
如何在Swift中检查对象是否属于给定类型?
答案 0 :(得分:259)
如果要检查特定类型,可以执行以下操作:
if let stringArray = obj as? [String] {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
你可以使用“as!”如果obj
不是[String]
let stringArray = obj as! [String]
您也可以一次检查一个元素:
let items : [Any] = ["Hello", "World"]
for obj in items {
if let str = obj as? String {
// obj is a String. Do something with str
}
else {
// obj is not a String
}
}
答案 1 :(得分:160)
现在可以在Swift 2.2 - 5中执行:
if object is String
{
}
然后过滤你的数组:
let filteredArray = originalArray.filter({ $0 is Array })
如果您要检查多种类型:
switch object
{
case is String:
...
case is OtherClass:
...
default:
...
}
答案 2 :(得分:148)
如果您只想知道对象是某个给定类型的子类型,那么有一种更简单的方法:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
func area (shape: Shape) -> Double {
if shape is Circle { ... }
else if shape is Rectangle { ... }
}
“使用类型检查运算符(是)检查实例是否确定 子类型。如果实例是,则类型检查运算符返回true 该子类类型,如果不是,则为false。“摘自:Apple Inc.”Swift编程语言。“iBooks。
在上面,“某个子类型”的短语很重要。编译器接受is Circle
和is Rectangle
的使用,因为该值shape
被声明为Shape
(Circle
和Rectangle
的超类)。
如果使用原始类型,则超类将为Any
。这是一个例子:
21> func test (obj:Any) -> String {
22. if obj is Int { return "Int" }
23. else if obj is String { return "String" }
24. else { return "Any" }
25. }
...
30> test (1)
$R16: String = "Int"
31> test ("abc")
$R17: String = "String"
32> test (nil)
$R18: String = "Any"
答案 3 :(得分:19)
我有两种方法:
if let thisShape = aShape as? Square
或者:
aShape.isKindOfClass(Square)
这是一个详细的例子:
class Shape { }
class Square: Shape { }
class Circle: Shape { }
var aShape = Shape()
aShape = Square()
if let thisShape = aShape as? Square {
println("Its a square")
} else {
println("Its not a square")
}
if aShape.isKindOfClass(Square) {
println("Its a square")
} else {
println("Its not a square")
}
编辑:3现在:
let myShape = Shape()
if myShape is Shape {
print("yes it is")
}
答案 4 :(得分:14)
for swift4:
if obj is MyClass{
// then object type is MyClass Type
}
答案 5 :(得分:9)
假设 drawTriangle 是UIView的实例。要检查drawTriangle是否为UITableView类型:
在 Swift 3 中,
if drawTriangle is UITableView{
// in deed drawTriangle is UIView
// do something here...
} else{
// do something here...
}
这也适用于您自己定义的类。您可以使用它来检查视图的子视图。
答案 6 :(得分:4)
为什么不使用专门为此任务构建的内置功能?
let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)
Result: "Array<Any>"
答案 7 :(得分:4)
警告此事:
var string = "Hello" as NSString
var obj1:AnyObject = string
var obj2:NSObject = string
print(obj1 is NSString)
print(obj2 is NSString)
print(obj1 is String)
print(obj2 is String)
所有四个最后一行都返回true,这是因为如果你输入
var r1:CGRect = CGRect()
print(r1 is String)
...当然打印“假”,但警告说从CGRect转换为String失败。因此某些类型被桥接,而'is'关键字调用隐式强制转换。
你应该更好地使用其中一个:
myObject.isKind(of: MyClass.self))
myObject.isMember(of: MyClass.self))
答案 8 :(得分:2)
为什么不使用这样的东西
fileprivate enum types {
case typeString
case typeInt
case typeDouble
case typeUnknown
}
fileprivate func typeOfAny(variable: Any) -> types {
if variable is String {return types.typeString}
if variable is Int {return types.typeInt}
if variable is Double {return types.typeDouble}
return types.typeUnknown
}
在Swift 3中。
答案 9 :(得分:2)
如果您只是想检查类而没有收到警告,因为未使用的定义值(让someVariable ......),您可以简单地用布尔值替换let东西:
if (yourObject as? ClassToCompareWith) != nil {
// do what you have to do
}
else {
// do something else
}
当我使用let方式并且没有使用定义的值时,Xcode提出了这个。
答案 10 :(得分:1)
斯威夫特3:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
if aShape.isKind(of: Circle.self) {
}
答案 11 :(得分:1)
myObject as? String
不是nil
,则 myObject
会返回String
。否则,它会返回String?
,因此您可以使用myObject!
访问字符串本身,或者安全地使用myObject! as String
投放该字符串。
答案 12 :(得分:1)
as?
不会总是给您预期的结果,因为as
不会测试数据类型是否为特定类型,但仅当数据类型可以转换为或表示为特定种类。
例如考虑以下代码:
func handleError ( error: Error ) {
if let nsError = error as? NSError {
每个符合Error
协议的数据类型都可以转换为NSError
对象,因此总是成功。但这并不意味着error
实际上是NSError
对象或其子类。
正确的类型检查将是:
func handleError ( error: Error ) {
if type(of: error) == NSError.self {
但是,这只会检查确切的类型。如果您还想包含NSError
的子类,则应使用:
func handleError ( error: Error ) {
if error is NSError.Type {
答案 13 :(得分:0)
如果你有这样的回应:
{
"registeration_method": "email",
"is_stucked": true,
"individual": {
"id": 24099,
"first_name": "ahmad",
"last_name": "zozoz",
"email": null,
"mobile_number": null,
"confirmed": false,
"avatar": "http://abc-abc-xyz.amazonaws.com/images/placeholder-profile.png",
"doctor_request_status": 0
},
"max_number_of_confirmation_trials": 4,
"max_number_of_invalid_confirmation_trials": 12
}
并且您要检查将被读作AnyObject的值is_stucked
,您只需要这样做
if let isStucked = response["is_stucked"] as? Bool{
if isStucked{
print("is Stucked")
}
else{
print("Not Stucked")
}
}
答案 14 :(得分:0)
如果您不知道在服务器的响应中会得到一个字典数组或单个字典,则需要检查结果是否包含数组。
在我的情况下,除了一次之外总是收到一系列字典。所以,为了处理我使用下面的swift 3代码。
if let str = strDict["item"] as? Array<Any>
在这里? Array检查获取的值是否为数组(字典项)。在其他情况下,如果它是单个字典项目,则可以处理,而不是保留在数组中。
答案 15 :(得分:0)
Swift 4.2,就我而言,使用isKind函数。
isKind(of :) 返回一个布尔值,该值指示接收方是给定类的实例还是从该类继承的任何类的实例。
i=1
阅读更多https://developer.apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind
答案 16 :(得分:0)
仅出于完整性考虑,基于接受的答案和其他一些观点:
let items : [Any] = ["Hello", "World", 1]
for obj in items where obj is String {
// obj is a String. Do something with str
}
但是您也可以(compactMap
也“映射” filter
没有的值):
items.compactMap { $0 as? String }.forEach{ /* do something with $0 */ ) }
以及使用switch
的版本:
for obj in items {
switch (obj) {
case is Int:
// it's an integer
case let stringObj as String:
// you can do something with stringObj which is a String
default:
print("\(type(of: obj))") // get the type
}
}
但是要坚持这个问题,检查它是否是一个数组(即[String]
):
let items : [Any] = ["Hello", "World", 1, ["Hello", "World", "of", "Arrays"]]
for obj in items {
if let stringArray = obj as? [String] {
print("\(stringArray)")
}
}
或更笼统(请参见this other question answer):
for obj in items {
if obj is [Any] {
print("is [Any]")
}
if obj is [AnyObject] {
print("is [AnyObject]")
}
if obj is NSArray {
print("is NSArray")
}
}
答案 17 :(得分:0)
Swift 5.2 & Xcode版本:11.3.1(11C504)
这是我检查数据类型的解决方案:
if let typeCheck = myResult as? [String : Any] {
print("It's Dictionary.")
} else {
print("It's not Dictionary.")
}
我希望它能对您有所帮助。