user3745635
user3745635

Reputation: 965

How to use selector function from different class in iOS Swift, mainly for NotificationCenter

I am using Tab Bar Controller in an iOS app and I am using reachability for checking the network availability and for achieving it I am using Notifications.

The basic syntax of a notification in Swift 3 is as follows -

NotificationCenter.default.addObserver(observer: Any, selector: Selector, name: NSNotification.Name?, object: Any)

and things happen generally this way -

NotificationCenter.default.addObserver(observer: self, selector: #selector(ViewControllerName.functionName), name: NameOfTheNotification, object: nil)

What I want to do is -

I want to use a static function present in different class for selector i.e.., when this notification is generated I want to call the static function which is present in the different class.

let's say the class name is "Functions" and the name of function is "myFunction()"

in simple words what I want to do is whenever the notification is there I want to call myFunction() function from class Functions.

What I had tried

I had tried doing this but it doesn't help -

NotificationCenter.default.addObserver(observer: Functions(), selector: #selector(Functions.myFunction), name: NameOfTheNotification, object: nil)

There occurs an error and that error is as follows - I had attached the Xcode snapshot below. shapshot of the error

Upvotes: 0

Views: 1645

Answers (3)

Ricowere
Ricowere

Reputation: 707

An illustration of why you have to retain Functions()

class Foo {
    @objc func test() {
        print("Hello")
    }
}

var foo: Foo? = Foo()
let nc = NotificationCenter.default

nc.addObserver(foo!,
               selector: #selector(Foo.test),
               name: NSNotification.Name(rawValue: "Barrr"),
               object: nil)

nc.post(name: NSNotification.Name(rawValue: "Barrr"), object: nil)
nc.post(name: NSNotification.Name(rawValue: "Barrr"), object: nil)

foo = nil

nc.post(name: NSNotification.Name(rawValue: "Barrr"), object: nil)

This will print Hello twice instead of three times because foo class was deallocated before the third call.

Upvotes: 0

kennytm
kennytm

Reputation: 523334

The easiest fix is to add @objc to reachabilityStatusChanged.

// ↓
@objc func reachabilityStatusChanged(notification: Notification) { 
    ...
}

But NotificationCenter doesn't really require your class to support Objective-C. You could use the block variant of the method:

NotificationCenter.default.addObserver(forName: Notification.Name("ReachStatusChanged"), object: nil, queue: nil) { notification in
    // do whatever Swift code with `notification` here.
    // no need to add @objc anywhere.
    reachabilityStatusChanged(notification)
}

Upvotes: 1

Ricowere
Ricowere

Reputation: 707

The main problem you're experimenting here is the interoperability with obj-C.

Make sure you expose the function `reachabilityStatusChanged' to obj-C with the @objc annotation.

@objc func reachabilityStatusChanged

Also, make sure the class Functions is visible to obj-c. (Inheriting it from NSObject)

Upvotes: 0

Related Questions