How to check the type of a variable against anothe

2020-07-17 14:33发布

I have an array of classes, and I want to check if a certain variable matches a certain element in that array. This is what I would do in Objective-C:

NSArray *arrayOfClasses = @[UIButton.class, UILabel.class];
Class aClass = arrayOfClasses[0];
UIButton *button = [UIButton new];

if ([button isKindOfClass:aClass]) {
    NSLog("button is aClass")
}

But I can't figure out a way to do it in Swift:

let arrayOfClasses = [UIButton.self, UILabel.self]
let aClass = arrayOfClasses[0] as! NSObject.Type
let button = UIButton()

if button is aClass {
    NSLog("button is aClass")
}

The code above throws an error saying 'aClass' is not a type. I've also tried as! AnyClass, as! AnyClass.Type, as! AnyObject.Type, etc.


Updated: Thanks to @matt, I now know how to get it to work in pure Swift. But if arrayOfClasses is created in Objective-C, it crashes with an error Could not cast value of type 'DummyA' (0x1049f48a0) to 'Swift.AnyObject.Type'. That make sense, because the Objective-C class is now an AnyObject in swift, and it can't convert that AnyObject to an AnyClass.

Here's the sample code:

@interface DummyA : NSObject
+ (NSArray *)dummies;
@end

@interface DummyB : NSObject
@end

@implementation DummyA
+ (NSArray *)dummies
{
    return @[[DummyA class], [DummyA class], [DummyB class], [DummyB class]];
}
@end

@implementation DummyB
@end


let arrayOfClasses = DummyA.dummies()
let aClass: AnyClass = arrayOfClasses[0] as! AnyClass // crash!

I finally found a way to make it to work, but that looks too weird to be the right way!

let aClass = NSClassFromString( NSStringFromClass( object_getClass(arrayOfClasses[0]) ))
// aClass is (AnyClass!) $R0 = DummyA

标签: swift
1条回答
够拽才男人
2楼-- · 2020-07-17 15:09

Tricky, isn't it? I think this will do it:

let arrayOfClasses : [AnyClass] = [UIButton.self, UILabel.self]
let AClass : AnyClass = arrayOfClasses[0]
let button = UIButton()
let ok = button.dynamicType === AClass // true

Line 1: If you don't declare the type of arrayOfClasses explicitly, you get an implicit array of AnyObject, and that's going to give you trouble later because an AnyObject can't be a class.

Line 2: AClass will implicitly be AnyClass, which is right, but we need explicit typing to quiet a warning from the compiler.

Line 3: No problem there.

Line 4: Well, basically you just have to know that this is a way to ask whether one thing's type is another given type. The class of button, as a class object, is its dynamicType, so now you can ask, is this the very same class object as whatever class object AClass is.


EDIT: You've edited the question so that the array of classes comes from Objective-C, but I don't see how that really changes anything:

let arrayOfClasses = DummyA.dummies()
let AClass : AnyObject = arrayOfClasses[0]
let button = UIButton()
let ok = button.dynamicType === AClass.self
查看更多
登录 后发表回答