Oluşan bir dizi var AnyObject. Üzerinde yineleme ve dizi örnekleri olan tüm öğeleri bulmak istiyorum.
Swift'te bir nesnenin belirli bir türde olup olmadığını nasıl kontrol edebilirim?
Oluşan bir dizi var AnyObject. Üzerinde yineleme ve dizi örnekleri olan tüm öğeleri bulmak istiyorum.
Swift'te bir nesnenin belirli bir türde olup olmadığını nasıl kontrol edebilirim?
Yanıtlar:
Belirli bir türe karşı kontrol etmek istiyorsanız aşağıdakileri yapabilirsiniz:
if let stringArray = obj as? [String] {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
"Gibi!" ve bu objtür değilse bir çalışma zamanı hatası atar[String]
let stringArray = obj as! [String]
Ayrıca bir kerede bir öğeyi kontrol edebilirsiniz:
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
}
}
?vermez. Kulağa benziyor asve ?birleştirildiğinde çalışma zamanı kontrolü yapacak. Ne zaman asolmadan kullanmak uygun olur ?? Şimdiden teşekkürler.
as, ?çünkü program yoksa hemen durur. Kullanılması ?halinde ifaçıklamaya programı devam etmesini sağlar.
?Bu durumda kullanmanın evet durumunda if deyimine, eğer değilse, diğer maddeye "genel" tipte bir kontrol gerçekleştireceğini düşündüm . ?Başka olmadan asla girilmez ve işaret ettiğiniz gibi bir çalışma zamanı hatasına neden olur. Tekrar teşekkürler.
?Atama dönmek için izin verir nildönüşüne eğer deyimi neden falsebaşka açıklamaya üzerinden düşen ve bu nedenle. Ancak, açıklamanın anlayışa yardımcı olduğunu düşünüyorum, ancak if letaslında derleyicide özel bir durum
In Swift 2,2-5 şimdi yapabilirsiniz:
if object is String
{
}
Ardından dizinizi filtrelemek için:
let filteredArray = originalArray.filter({ $0 is Array })
Kontrol etmek için birden fazla türünüz varsa:
switch object
{
case is String:
...
case is OtherClass:
...
default:
...
}
objectbir şekilde Stringsahip iken, (Swift 2 en az) parantez içindeki letsolüsyon bunu yapabilirsiniz.
objectblokta kullanmak iyidir.
object.uppercaseString, değişkenin türü bu türe String
Yalnızca bir nesne olmadığını bilmek istiyorsanız olduğu belirli bir türden bir alt tipi sonra daha basit bir yaklaşım vardır:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
func area (shape: Shape) -> Double {
if shape is Circle { ... }
else if shape is Rectangle { ... }
}
“Bir örneğin belirli bir alt sınıf türünde olup olmadığını kontrol etmek için tür kontrol operatörünü (is) kullanın. Tür denetim operatörü, örnek bu alt sınıf türündeyse true değerini, değilse false değerini döndürür. ” Alıntı: Apple Inc. “Hızlı Programlama Dili”. iBooks .
Yukarıda 'belirli bir alt sınıf türünden' ifadesi önemlidir. Kullanımı is Circleve is Rectanglebu değer, çünkü derleyici tarafından kabul edilir shapeolarak bildirilmiş Shape(a superclass Circleve Rectangle).
İlkel türler kullanıyorsanız, üst sınıf olacaktır Any. İşte bir örnek:
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"
isyine de burada çalışır? Teşekkürler.
objectOlarak ilan ederseniz çalışmalıdır Any. Bir örnekle güncellendi.
AnyObjectönerilen aşağıdaki cevaba göre, AnyObjectmiras alınmadığı için çarpıtılmış gibi görünüyor NSObject. Farklıysa Any, bu aslında harika bir çözüm olacaktır. Teşekkürler.
Bunu yapmanın 2 yolu var:
if let thisShape = aShape as? Square
Veya:
aShape.isKindOfClass(Square)
İşte ayrıntılı bir örnek:
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")
}
Düzenleme: 3 şimdi:
let myShape = Shape()
if myShape is Shape {
print("yes it is")
}
isKindOfClassNSObjectprotokolün bir yöntemidir ; sadece onu benimseyen sınıflar için çalışmalıdır (NSObject'ten inen tüm sınıflar ve bunu açıkça benimseyen herhangi bir özel Swift sınıfı)
Varsayalım drawTriangle drawTriangle tipi UITableView olup olmadığını UIView.To çek bir örneğidir:
Gelen Swift 3 ,
if drawTriangle is UITableView{
// in deed drawTriangle is UIView
// do something here...
} else{
// do something here...
}
Bu, kendiniz tanımladığınız sınıflar için de kullanılabilir. Bir görünümün alt görünümlerini kontrol etmek için bunu kullanabilirsiniz.
Neden bu görev için özel olarak oluşturulmuş yerleşik işlevselliği kullanmıyorsunuz?
let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)
Result: "Array<Any>"
Bu konuda uyarınız:
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)
Son dört satırın tümü true değerini döndürür, çünkü
var r1:CGRect = CGRect()
print(r1 is String)
... elbette "yanlış" yazıyor, ancak bir Uyarı CGRect'ten String'e Yayınlama işleminin başarısız olduğunu söylüyor. Bu nedenle, bazı türler köprülenir ve 'is' anahtar sözcüğü örtük bir kadro çağırır.
Bunlardan birini daha iyi kullanmalısınız:
myObject.isKind(of: MyClass.self))
myObject.isMember(of: MyClass.self))
Sınıfı yalnızca kullanılmayan tanımlı değer nedeniyle bir uyarı almadan kontrol etmek istiyorsanız (let someVariable ...), let öğelerini bir boole ile değiştirebilirsiniz:
if (yourObject as? ClassToCompareWith) != nil {
// do what you have to do
}
else {
// do something else
}
Xcode, let yolunu kullandığımda ve tanımlanan değeri kullanmadığımda bunu önerdi.
Neden böyle bir şey kullanmıyorsun?
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'te.
Swift 4.2, Benim durumumda isKind işlevini kullanma.
isKind (of :) Alıcının belirli bir sınıf örneği mi yoksa o sınıftan miras alan herhangi bir sınıf örneği mi olduğunu gösteren bir Boolean değeri döndürür.
let items : [AnyObject] = ["A", "B" , ... ]
for obj in items {
if(obj.isKind(of: NSString.self)){
print("String")
}
}
Readmore https://developer.apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind
Sadece kabul edilen cevaba ve diğerlerine dayanan tamlık uğruna:
let items : [Any] = ["Hello", "World", 1]
for obj in items where obj is String {
// obj is a String. Do something with str
}
Ancak şunları da yapabilirsiniz ( olmayan compactMapdeğerleri "eşleştirir" filter):
items.compactMap { $0 as? String }.forEach{ /* do something with $0 */ ) }
Ve aşağıdakileri kullanan bir sürüm 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
}
}
Ancak soruya sadık kalmak, bunun bir dizi olup olmadığını kontrol etmek (yani [String]):
let items : [Any] = ["Hello", "World", 1, ["Hello", "World", "of", "Arrays"]]
for obj in items {
if let stringArray = obj as? [String] {
print("\(stringArray)")
}
}
Veya daha genel olarak ( bu diğer soru cevabına bakınız ):
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")
}
}
as?her zaman beklenen sonucu asvermez, çünkü bir veri türünün belirli bir tür olup olmadığını test etmez , ancak yalnızca bir veri türünün belirli bir türe dönüştürülebilir veya temsil edilebildiğini test eder .
Örneğin bu kodu düşünün:
func handleError ( error: Error ) {
if let nsError = error as? NSError {
ErrorProtokole uyan her veri türü bir NSErrornesneye dönüştürülebilir , böylece bu her zaman başarılı olacaktır . Ancak bu erroraslında bir NSErrornesne ya da onun bir alt sınıfı olduğu anlamına gelmez .
Doğru tip kontrolü şu şekildedir:
func handleError ( error: Error ) {
if type(of: error) == NSError.self {
Ancak, bu yalnızca tam türü kontrol eder. Ayrıca alt sınıfını da eklemek NSErroristiyorsanız şunu kullanmalısınız:
func handleError ( error: Error ) {
if error is NSError.Type {
Böyle bir Yanıtınız varsa:
{
"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
}
ve is_stuckedAnyObject olarak okunacak değeri kontrol etmek istiyorsanız , tek yapmanız gereken bu
if let isStucked = response["is_stucked"] as? Bool{
if isStucked{
print("is Stucked")
}
else{
print("Not Stucked")
}
}
Sunucudan gelen yanıtta bir dizi sözlük veya tek bir sözlük alacağınızı bilmiyorsanız, sonucun bir dizi içerip içermediğini kontrol etmeniz gerekir.
Benim durumumda her zaman bir kez dışında bir dizi sözlük almak. Yani, ele almak için ben hızlı 3 için aşağıdaki kodu kullandım.
if let str = strDict["item"] as? Array<Any>
Burada olduğu gibi? Dizi, elde edilen değerin dizi (sözlük öğelerinin) olup olmadığını kontrol eder. Aksi takdirde, bir dizinin içinde tutulmayan tek bir sözlük öğesi olup olmadığını işleyebilirsiniz.
Swift 5.2 ve Xcode Sürümü: 11.3.1 (11C504)
İşte veri türü kontrol benim çözüm:
if let typeCheck = myResult as? [String : Any] {
print("It's Dictionary.")
} else {
print("It's not Dictionary.")
}
Umarım bu sana yardımcı olur.