0

I've got a base class. In this base class I take some callbacks in the init method. In these callbacks I'd like to reference the derived class's self. However, Swift complains that the lambdas reference self before super.init. Of course, I know that in reality, the base class doesn't invoke the callbacks actually inside super.init and even if it did, that's not clearly illegal, since it would not be before super.init.

How can I pass a callback to super.init that references self?

Puppy
  • 144,682
  • 38
  • 256
  • 465

2 Answers2

1

It is not possible to reference self in anyway before you have called the super.init. self can only be referenced when the initialisation is done. You have to look for alternative ways to create your object (factory methods, builder pattern).

Kirsteins
  • 27,065
  • 8
  • 76
  • 78
  • But callbacks don't actually reference `self`. They only allow `self` to be referenced *in the future*. Only invoking the callback actually references `self`. – Puppy Jul 28 '15 at 09:52
  • There is no mechanism that would ensure that those callbacks are not called prematurely before initialisation is done. – Kirsteins Jul 28 '15 at 09:54
  • Sure there is. It's called "I wrote the code that consumes these callbacks and ensured that I did not do that". – Puppy Jul 28 '15 at 09:56
  • @Puppy Yes, but you cannot tell that to compiler. Unless there are new mechanism introduced that allows you to reference instance that is in progress of initialisation with promise to not use it until its read. Swift initialisation is really strict. – Kirsteins Jul 28 '15 at 09:59
  • The whole point of Swift is not to allow anything that is potentially dangerous. That's the whole trouble with C, C++, Objective-C that allow you to carry loaded guns so you can shoot yourself in the foot. Swift doesn't allow it. Anyway, your question was "How can I" and the correct answer given by Kirsteins was "You can't". Anything else doesn't matter. – gnasher729 Jul 28 '15 at 10:00
  • @gnasher729: Swift is not even remotely more safe than C++. Now I'm using a gimped unsafe design because you can't initialize things properly. – Puppy Jul 28 '15 at 10:07
1

I managed to work around this meaningless restriction by refactoring the class somewhat. Instead of simply passing the constructor the data it needs directly, instead there's a getter for the data which just happens to be called exactly once by the superclass constructor. The variable that stores this data, instead of being immutable and proper, now is initialized with nil (i.e. left uninitialized) and then initialized later through the getter and then there's another getter-only computed property.

So now anyone who tries to read the class will be thoroughly confused by the worthless meandering around the point, but it does actually have the desired semantics.

Puppy
  • 144,682
  • 38
  • 256
  • 465