allenlinli
allenlinli

Reputation: 2154

How to perform a class method of a class which is casted from NSClassFromString?

I tried to use a class which is created from NSClassFromString to perform a class method, but I failed.

In Objective-C, it's easy:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:[NSClassFromString(reuseIdentifier) cellStyle] reuseIdentifier:reuseIdentifier];
    if (self) {
         let sel = #selector(CTFeedbackTopicCellItem.cellStyle())
        // Initialization code
    }
    return self;
}

And in Swift it's not easy:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    if let reuseIdentifier2 = reuseIdentifier
    {
        if let class2 = NSClassFromString(reuseIdentifier2) as? NSObjectProtocol
        {
            let sel = #selector(CTFeedbackCellItem.cellStyle())

            if let class3 = class2 as? CTFeedbackCellItem
            {
                super.init(style: class3.cellStyle, reuseIdentifier: reuseIdentifier2)
            }
        }
    }
}

The error shown in my Swift code so far are:
1. Argument of '#selector' does not refer to an '@objc' method, property or initializer.
2. Stastic member 'cellType' cannnot be used on instance of type 'CTFeedbackCellItem'

Upvotes: 1

Views: 503

Answers (1)

OOPer
OOPer

Reputation: 47896

Try this:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    guard let reuseIdentifier = reuseIdentifier else {
        fatalError("bad usage")
    }
    guard let itemClass = NSClassFromString(reuseIdentifier) as? CTFeedbackCellItem.Type else {
        fatalError("bad reuseIdentifier")
    }
    super.init(style: itemClass.cellStyle(), reuseIdentifier: reuseIdentifier)
}

(If you have implemented your cellStyle as a class property, change itemClass.cellStyle() to itemClass.cellStyle.)

Class object is not an instance of the class, so you should not cast it like an instance. Cast it to meta-class, if you want to call class methods. No need to use #selector.

Upvotes: 2

Related Questions