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 obj
tü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 as
ve ?
birleştirildiğinde çalışma zamanı kontrolü yapacak. Ne zaman as
olmadan kullanmak uygun olur ?
? Şimdiden teşekkürler.
as
, ?
çünkü program yoksa hemen durur. Kullanılması ?
halinde if
açı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 nil
dönüşüne eğer deyimi neden false
başka açıklamaya üzerinden düşen ve bu nedenle. Ancak, açıklamanın anlayışa yardımcı olduğunu düşünüyorum, ancak if let
aslı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:
...
}
object
bir şekilde String
sahip iken, (Swift 2 en az) parantez içindeki let
solüsyon bunu yapabilirsiniz.
object
blokta 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 Circle
ve is Rectangle
bu değer, çünkü derleyici tarafından kabul edilir shape
olarak bildirilmiş Shape
(a superclass Circle
ve 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"
is
yine de burada çalışır? Teşekkürler.
object
Olarak ilan ederseniz çalışmalıdır Any
. Bir örnekle güncellendi.
AnyObject
önerilen aşağıdaki cevaba göre, AnyObject
miras 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")
}
isKindOfClass
NSObject
protokolü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 compactMap
değ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 as
vermez, çü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 {
Error
Protokole uyan her veri türü bir NSError
nesneye dönüştürülebilir , böylece bu her zaman başarılı olacaktır . Ancak bu error
aslında bir NSError
nesne 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 NSError
istiyorsanı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_stucked
AnyObject 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.