10

Let's say I have a class

public class MyClass: NSObject, ABCDelegate {
    func delegateMethod(a: a, b: b) {
        ...
    }
}

This delegate method is being called by a singleton in MyClass that handles some networking operations.

The thing is the compiler complains about Method 'delegateMethod(...)' must be declared public because it matches a requirement in public protocol 'ABCDelegate'.

My question is:

  1. Why exactly is the compiler complaining for the method being declared as private func or simply func
  2. How can I declare the ABCDelegate methods to be private to this class?
Thanos
  • 844
  • 2
  • 11
  • 27

1 Answers1

9

If ABCDelegate is declared public and MyClass which adopts it is declared public, then the MyClass implementation of any members required by ABCDelegate must be declared public. It's as simple as that.

And if you think about it, it couldn't work any other way. Knowledge of MyClass is public. Knowledge of ABCDelegate is public. Knowledge of the fact that MyClass adopts ABCDelegate is public. Therefore knowledge of the fact MyClass implements the required members of ADCDelegate must be public - it follows as the night the day.

If you really wanted to, you could work around this by inserting a nonpublic object type into the chain of command. This compiles fine:

public protocol Proto {
    func f()
}
public class A {
    private var helper : B!
    func g() {
        helper.f()
    }
}
private class B : Proto {
    func f() {}
}

But it seems awfully silly. My recommendation is just do what the compiler tells you and move on.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • The rules generally makes sense if you think about them a little. They are fully spelled out in the docs - https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html But in general you don't need to know them because, as here, the compiler tells you if you violate one! – matt Feb 04 '15 at 19:29
  • And see also the discussion in my new Swift tutorial: http://www.apeth.com/swiftBook/ch05.html#_privacy_rules – matt Feb 04 '15 at 19:30
  • Matt, that makes sense. The thing is, I didn't write ABCDelegate and it's actually consumed via the bridging header from it's respective Obj-C framework. I want to be "politically" correct and have it as a private method in my class. Options? – Thanos Feb 04 '15 at 19:32
  • None. Do what the compiler makes you do and move on. See the link in my tutorial that I pointed you to for another example of the same thing. – matt Feb 04 '15 at 19:34
  • Of course you could adopt ABCDelegate in a non-public object type and have your public object use that. But really, it seems pointless to worry about this. It's a lot better than in Swift `0.1` where _everything_ was public! – matt Feb 04 '15 at 19:35
  • Added to my answer an example of inserting a nonpublic class into the chain. – matt Feb 04 '15 at 19:40