0

I'm trying to call method of Class B from class A on the button tap event. But it does not work and below is my code.

// Viewcontroller
class ViewController: UIViewController {
   @IBAction func btnClicked(_ sender: Any) {
        var objA = A()
        objA.delegate?.TestA()
    }
}

// ClassA.swift
protocol TestA {
    func TestA()
}

class A {
    var delegate: TestA?
}


// ClassB.swift
class B : TestA {
    func TestA() {
        print(" Function A from b")
    }
}

When tapping a button, function TestA() does not invoke.

I even tried the code below, but it also didn't work:

var objB = B()
var objA = A()
objA.delegate = objB
faforito
  • 19
  • 1
  • 5

3 Answers3

1

Because you instantiate instance of Class A using

    var objA = A()

Clearly you haven't initialised delegate property in A because its optional its default value is nil

Now when you call

    objA.delegate?.TestA()

delegate is nil hence function TestA will not be called

Suggestion

Always use camelCasing for declaring names of functions. So TestA() is incorrect rather use testA()

EDIT 1:

Tested this

@IBAction func btnClicked(_ sender: Any) {
    let objA = A()
    let objB = B()
    objA.delegate = objB
    objA.delegate?.TestA()
}

This is working fine what is the issue?

Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78
  • @manisha-upadhyay: Thank you for accepting the answer, what was the issue ? – Sandeep Bhandari Feb 13 '19 at 10:03
  • The **EDIT 1** above will work but does not benefit from defining the `protocol TestA`. This will work even when `class B` is not conforming to `protocol TestA`. See my answer bellow for explanation. – Pankaj Kulkarni Feb 14 '19 at 06:01
1

The objA.delegate is never assigned to an object, so it has an initial value of nil. The ? operator avoids calling a function on a nil object.

Daniel
  • 8,794
  • 4
  • 48
  • 71
0

The answer by Sandeep Bhandari is right.

Some information for better understanding of Protocol and Delegates. TestA is a protocol and an optional var delegate is defined in class A. This setup is right. The idea behind this setup is that any user of class A, in this case class B which conforms to protocol TestA gets a callback from class A. You need to call the delegate.testA() function from within class A. The current implementation of ViewController is not at all benefiting from defining Protocol and Delegates.

To achieve proper usage, the class A cab be modified as follows:

protocol TestA {
    func testA()
}

class A {
        var delegate: TestA?
        func process() {
            // Do something and call delegate function to report it.
            delegate?.testA()
        }
    }

And modify ViewController as follows (copied class B for completeness):

class ViewController: UIViewController {
    @IBAction func btnClicked(_ sender: Any) {
        var objA = A()
        var objB = B()
        objA.delegate = objB
        objA.process()
    }
}

// ClassB.swift
class B : TestA {

    func TestA() {
        print(" Function A from b")
    }
}

Now function implemented in class B to conform to protocol TestA will be called when process() function on objA of class A is called. This is better use of Protocol and Delegate. Hope this helps.

Pankaj Kulkarni
  • 553
  • 4
  • 12