简体   繁体   中英

Xcode 10 - UIButton custom deallocated property is weak in Swift 4

I've had this code working perfectly and still is, but I seem to be seeing a warning message of :

Instance will be immediately deallocated because property "selectButton" is weak

This is only to change the button images to different sizes depending on whether its a iPad or iPhone, due to the size of screen, I have tried to change to :

  @IBOutlet var selectButton : UIButton?

Then add to ViewDidLoad() this for the custom button:

  selectButton = UIButton(type: .custom)

But when app compiled, the image doesn't appear like it used too.

Ive been look everywhere for a fix for this and cant seem to find it, can any help with this?

I have added my code below:

  @IBOutlet weak var selectButton = UIButton(type: .custom)

  var bluBtnIphn : String = "blue_iPhone_btn.png"
  var orgBtnIphn : String = "org_iPhone_btn.png"

  switch UIDevice.current.userInterfaceIdiom {
  case .phone:
      print(tag,"iPhone Used")
      selectButton?.setImage(UIImage(named: bluBtnIphn), for: .normal)
      selectButton?.setImage(UIImage(named: orgBtnIphn), for: .highlighted)
  case .pad:
      print(tag,"iPad Used")
      selectButton?.setImage(UIImage(named: bluBtnIpad), for: .normal)
      selectButton?.setImage(UIImage(named: orgBtnIpad), for: .highlighted)
  case .unspecified:
      print("Unknown device..")
  default:
      break
  }

Objects are deallocated when there are no strong references to them any more.

In your case your view controller only has a weak reference to the button.

And because you're instantiating it in code. That is the only reference to it.

The reason you are getting confused is because you are getting mixed up with buttons created in nibs/storyboards and buttons created in code.

When you create a button from a nib or storyboard it looks like this...

@IBOutlet weak var someButton: UIButton!
  • @IBOutlet tells Xcode this is an Interface Builder connected object
  • weak var it is weak in the view controller because the storyboard adds it to the view and the view then gets a strong reference to it.

In your case the storyboard is not creating it so change it to something like...

var selectButton = UIButton(type: .custom)

This will make it a strong reference and stop it from deallocating.

EDIT: After your latest comment...

If you're doing this via Interface Builder then don't create the button in code.

If you're doing it in Interface Builder then your code should be...

@IBOutlet weak var someButton: UIButton!

1 - You are creating outlet of button it is reference type is weak always, because when you use it you have check if it nil or not. you can't create like @IBOutlet weak var selectButton = UIButton(type: .custom).

2 - When you set image to button directly type name it shows image through autointelligence you don't need to set image likes this UIImage(named: bluBtnIphn), because you are creating varible and wasting memory.

3 - set image to button write in function and call from viewDidLoad() or viewWillAppear().

@IBOutlet weak var selectButton: UIButton!

    override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       setImageToButton()
    }

    func setImageToButton() {
      switch UIDevice.current.userInterfaceIdiom {
      case .phone:
          print(tag,"iPhone Used")
          selectButton?.setImage(bluBtnIphn, for: .normal)
          selectButton?.setImage(orgBtnIphn, for: .highlighted)
      case .pad:
          print(tag,"iPad Used")
          selectButton?.setImage(bluBtnIpad, for: .normal)
          selectButton?.setImage(orgBtnIpad, for: .highlighted)
      case .unspecified:
          print("Unknown device..")
      default:
          break
      }
}

Why using @IBOutlet ? You are allocating the button manually, then why you are using @IBOutlet.

@IBOutlet weak var selectButton = UIButton(type: .custom) // this is wrong

The above usage will give warning because no strong reference to the allocated button object so in ARC it will dealloc after allocating so selectButton will be nil.

Use like below for manual button allocation

var selectButton = UIButton(type: .custom)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM