jhk727
jhk727

Reputation: 225

Cannot downcast UIButton to a subclass

I have searched around and cannot figure out what I am doing wrong. I am trying to downcast a UIButton to a subclass in the following line of code:

var currentButton: FileButton = UIButton(type: .System) as! FileButton

FileButton is a simple subclass of UIButton that just stores a couple variables with the button. Code is below:

import UIKit

class FileButton: UIButton {

     var fileAddress: String = ""
     var fileMsgId: String = ""
     var fileAppId: String = ""

}

I am getting the following error in the console when I try to execute this code:

Could not cast value of type 'UIButton' (0x19e9c9e40) to 'CollectionFun.FileButton' (0x100127490).

Any thoughts? This seems like it should be simple but I can't figure it out. Thanks.

Upvotes: 0

Views: 239

Answers (3)

vigneshv
vigneshv

Reputation: 642

Like other object oriented languages, if you initialize a variable as a superclass (in your case UIButton) you cannot downcast it to a subclass (in your case FileButton). This is because you are initializing a UIButton object, which is not a FileButton. Simply change your code to initialize a FileButton object, and it should work.

You should therefore replace UIButton(type: .System) as! FileButton with FileButton(type: .System). Note that the cast is not necessary now, as we are directly initializing a FileButton object.

Upvotes: 0

Alexey Pichukov
Alexey Pichukov

Reputation: 3405

You can not downcast object in your example. You create UIButton type object and try to convert it to other object that not the parrent for it or is higher in the inheritance hierarchy , in this case new object have more functionality and need to allocate more memory for example. You can make your code compiled without error like this:

var currentButton = UIButton(type: .System) as? FileButton

but it will be useless code, because it will always return nil

To explain more clearly give an example. You can do this:

var button1 = FileButton()
button1.fileAddress = "qwerty"
var button2 = button1 as UIButton
var button3 = button2 as? FileButton
print(button3.fileAddress)

print will be

Optional("qwerty")

And it will be work becoause first object was FileButton type.

But this code:

var button1 = UIButton()
var button2 = button1 as? FileButton
print(button2?.fileAddress)

will print

nil

And you try to do like second example

Upvotes: 0

zuziaka
zuziaka

Reputation: 575

Just simply call:

var currentButton: FileButton = FileButton(type: .System)

Upvotes: 1

Related Questions