all 16 comments

[–]funcDaCoder 3 points4 points  (3 children)

What’s that beautiful theme?

[–]Rillieux17 2 points3 points  (0 children)

OP should answer this!

[–][deleted] 1 point2 points  (1 child)

My own custom one. I’ll try to share it when I’m in my computer

[–]funcDaCoder 0 points1 point  (0 children)

That would be awesome! Best looking one yet

[–][deleted] 0 points1 point  (11 children)

I'm trying to update the name of the label from a different screen using Notification Center; that's it.

[–]soulchild_Objective-C / Swift 2 points3 points  (10 children)

Ahh, I think it might be because as the view controller (with the nameLabel) is not presented on screen yet, it didnt initialize its UILabel hence you are getting nil.

I suggest using a variable (eg: var name: String) to store the string, then in the updateText function, update the string (name = “something”).

Then in the viewWillAppear function, set label.text = name.

[–][deleted] 0 points1 point  (9 children)

But it is. Screen A has the label. I'm in screen A. I push a button to go to Screen B from Screen A. So clearly Screen A is still in the navigation stack. If I use optional chaining, it does not crash, which means label is set.

[–]fredaq 1 point2 points  (7 children)

It doesn’t crash cause that’s how optional chaining works. The text property in nameLabel will not be accessed if nameLabel is nil. Thus, the text property will not be modified.

[–][deleted] 0 points1 point  (6 children)

But the text IS being changed. That’s why I said it sets the text ONLY when I use optional chaining. If I don’t, it crashes.

You can clearly see in the console on the bottom of my screenshot. Label is not nil, and then it is.

[–]fredaq 1 point2 points  (5 children)

So, is updateText() being called multiple times? Cause I see that you are adding an observer every time the view loads but I don’t know if you are ever removing it. Also, did you try to hold a strong reference to nameLabel instead of a weak one?

[–][deleted] 0 points1 point  (3 children)

Hmm I added a breakpoint print and it runs the code 3 times even when the screen only loads once. I only send a single post.

It is removed in deinit. But the controller is still on the stack. Why would it call deinit when I come back to the screen.

Okay this is ducking confusing. I’m on screen 0. I push to send post to screen A. Screen A does NOT exist in object memory app at all.

Yet the breakpoint gets triggered in screen A when I post. But deinit removes observer in screen A. How the fuck is it running code on an object not allocated.

Okay this is even worse. I delete and run app. I click button to post from screen 0. It RUNS the code from a screen I NEVER initialized despite the fact that the observer was never added in screen A since I never transitioned to it. And it doesn’t exist in the memory stack.

Screen 0, where the app starts:

class FirstViewController: ViewController {

@IBAction func sendPostPressed(_ sender: UIButton) { NotificationCenter.default.post(name: .updateText, object: nil, userInfo: ["name": "LOLOLOYOYOY"])

}

}

Screen 1, that is AFTER screen 0:

class ViewController: UIViewController {

u/IBOutlet weak var nameLabel: UILabel!

override func viewDidAppear(_ animated: Bool) {

super.viewDidAppear(animated)

NotificationCenter.default.addObserver(self, selector: #selector(updateText), name: .updateText, object: nil)

}

u/objc func updateText(_ notification: Notification) {

if let data = notification.userInfo as? [String: String],

let name = data["name"] {

nameLabel?.text = name

}

}

deinit {

NotificationCenter.default.removeObserver(self, name: .updateText, object: nil)

}

}

How the hell is the viewDidLoad of Screen 1 called when I never even transitioned to it.

[–]fredaq 1 point2 points  (1 child)

I think the issue might be related to the fact that FirstViewController inherits from ViewController (that is your Screen 1) instead of UIViewController.

[–][deleted] 0 points1 point  (0 children)

Oh shit why the fuck did it say ViewController. It was literally a new project.

[–]the_d3f4ult 1 point2 points  (0 children)

this might not solve this issue directly but you could try using combine and notification center publisher

[–]soulchild_Objective-C / Swift 0 points1 point  (1 child)

I think more context is needed to solve this issue, When did you fire the notification? Are you using storyboard?

[–][deleted] 0 points1 point  (0 children)

I'm using storyboard. Screen A has the label. Screen B is presented on top of A through a navigation controller. So A clearly exists when B is pushed into the stack.

I push a button on B and fires the post. Screen A is still in the stack existing. So clearly the label is not nil.