web-dev-qa-db-ja.com

Swiftでオブジェクトが与えられた型かどうかを調べる

私はAnyObjectで構成されている配列を持っています。それを反復処理して、配列インスタンスであるすべての要素を見つけます。

Swiftでオブジェクトが特定のタイプであるかどうかを確認する方法はありますか。

223
Encore PTL

特定の種類に対して確認したい場合は、次のようにします。

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]

一度に1つの要素をチェックすることもできます。

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
   }
}
256
drewag

Swift 2.2 - 4.0.3 でできること:

if object is String
{
}

それから配列をフィルタリングします。

let filteredArray = originalArray.filter({ $0 is Array })
158
meaning-matters

もしオブジェクト与えられた型のサブタイプであるかどうかだけ知りたいのなら、もっと簡単なアプローチがあります:

class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}

func area (shape: Shape) -> Double {
  if shape is Circle { ... }
  else if shape is Rectangle { ... }
}

インスタンスが特定のサブクラス型であるかどうかを確認するには、型チェック演算子(is)を使用します。型チェック演算子は、インスタンスがそのサブクラス型である場合はtrueを返し、そうでない場合はfalseを返します。」抜粋:Apple Inc.「The Swift Programming Language」 iBooks

上記では、「特定のサブクラス型の」という句が重要です。 is Circleおよびis Rectangleの使用は、その値shapeShapeCircleおよび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"
148
GoZoner

それには2つの方法があります。

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")
}
19
Esqarrouth

Swift4の場合:

if obj is MyClass{
    // then object type is MyClass Type
}
14
Ahmad Labeeb

drawTriangle がUIViewのインスタンスであると想定します。drawTriangleがUITableView型であるかどうかを確認します。

In Swift 3

if drawTriangle is UITableView{
    // in deed drawTriangle is UIView
    // do something here...
} else{
    // do something here...
}

これは自分で定義したクラスにも使用できます。これを使用してビューのサブビューを確認できます。

9
Yushan Zhang

このタスク専用に構築された組み込み機能を使用しないのはなぜですか。

let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)

Result: "Array<Any>"
4
Patrik Forsberg

これについて警告してください。

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) 

最後の4行はすべてtrueを返します。これは、次のように入力した場合に起こります。

var r1:CGRect = CGRect()
print(r1 is String)

...それはもちろん "false"を出力しますが、警告はCGRectからStringへのキャストが失敗することを示します。そのため、いくつかの型はブリッジされ、 'is'キーワードは暗黙のキャストを呼び出します。

あなたはこれらのうちの一つを使うべきです:

myObject.isKind(of: MyClass.self)) 
myObject.isMember(of: MyClass.self))
4
tontonCD

未使用の定義値(let someVariable ...)のために警告を表示せずにクラスをチェックしたいだけの場合は、単にletのものをブール値に置き換えることができます。

if (yourObject as? ClassToCompareWith) != nil {
   // do what you have to do
}
else {
   // do something else
}

Xcodeは、私がlet方法を使用し、定義された値を使用しなかったときにこれを提案しました。

2
the_mariooo

なぜこんな風に使わないの?

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では.

2
Dawy

スイフト3:

class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}

if aShape.isKind(of: Circle.self) {
}
1
Harris

nilmyObjectでない場合、myObject as? StringStringを返します。それ以外の場合は、String?を返すので、myObject!を使用して文字列自体にアクセスするか、myObject! as Stringを使用して安全にキャストできます。

1
cprcrack

受け入れられた答えと他のいくつかに基づく完全性のためだけに:

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)")
  }
}

またはより一般的には( この他の質問の答え を参照):

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")
  }
}
0
FranMowinckel

サーバーからの応答で辞書の配列または単一の辞書を受け取ることがわからない場合は、結果に配列が含まれているかどうかを確認する必要があります。
私の場合は、一回を除いて常に一連の辞書を受け取ります。そのため、Swift 3では以下のコードを使用しました。

if let str = strDict["item"] as? Array<Any>

これは?配列は取得した値が(辞書項目の)配列かどうかをチェックします。それ以外の場合は、配列内に保持されていない単一の辞書アイテムであるかどうかを処理できます。

0
V.S

Swift 4.2、私の場合はisKind関数を使う。

isKind(of :)レシーバが特定のクラスのインスタンスか、そのクラスから継承したクラスのインスタンスかを示すブール値を返します。

  let items : [AnyObject] = ["A", "B" , ... ]
  for obj in items {
    if(obj.isKind(of: NSString.self)){
      print("String")
    }
  }

続きを読む https://developer.Apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind

0
Tung Tran

このような応答がある場合:

{
  "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")
 }
}
0
Abo3atef