What you are looking for is an inner class (not necessarily anonymous) declared in a scope that allows it to access the count variable of the MyClass instance and accepts a protocol defined in a different scope. Swift has a few of these right now, but it doesn't look like you can put them all together in any compressed form you might be looking for.
You might consider declaring an inner class:
class MyView: UIView { let someComponent = SomeInnerComponent() // type SomeInnerComponent is inferred var count = 0 // type Int is inferred class Helper: SomeProtocol { func a0() { count-- } // ERROR // ... } init() { someComponent.delegate = Helper() } }
But this will not work, because count implicitly self.count , where self is an instance of Helper , and not an instance of MyView that "owns" an instance of Helper . And there is no way to reference this instance of MyView (or its properties) from Helper methods, because you could just build MyView.Helper() without having an existing instance of MyView . Inner classes (or nested types in general) in Swift nest only in the lexical domain, and not in existential property. (Or, to put it another way, since you are referencing Java: all inner classes in Swift are static inner classes in Java. There is no non-static inner class.) If you need this function, you might want to tell Apple that you want it .
You can also try declaring Helper inside MyView.init() - in Swift you can insert type definitions anywhere, including internal functions or methods of other types. Defined there, it can refer to MyView properties. However, now type information for Helper is visible only inside MyView.init() , so when you assign it to someComponent.delegate (whose type is just SomeProtocol ), you cannot use it ... it's even a compiler failure. (This is another error , but itโs hard to say whether the error is โcompiler crashes on actual useโ or โcode is bad,โ but the compiler crashes rather than creating an error. ")
The closest solution I can come up with is something like this:
class SomeInnerComponent { var delegate: SomeProtocol? } protocol SomeProtocol { func a0() func a1() } class MyClass { var someComponent = SomeInnerComponent() var count = 0 struct Helper: SomeProtocol { var dec: () -> () var inc: () -> () func a0() { dec() } func a1() { inc() } } init() { someComponent.delegate = Helper( dec: { self.count -= 1 },
How it works:
Helper - internal structure (may be a class, but structure is simpler)- It implements methods
a0 and a1 that satisfy SomeProtocol requirements - Implementations
a0 and a1 close dec and inc , which are stored properties (like instance variables) of the Helper struct - You record (or otherwise indicate) these closures when creating an instance of
Helper (using the default initializer, Helper(dec: (Void -> Void), inc: (Void -> Void)) ) - Because you can write closures during
Helper initialization, these locks can capture the variables in which you invoke the initializer, including the implicit self , which refers to the MyClass instance that creates the Helper .
You need both a0 / a1 and dec / inc , because you need to close (the last), not the methods, to capture the on state. Although locks and funcs / methods are largely interchangeable, you cannot create an implementation of the / func method by assigning a closure to the / func method name. (It would be different if SomeProtocol required a closure property instead of methods, but I assume SomeProtocol not under your control.)
In any case, this is a kind of many templates and an abstraction layer that you might not need, so itโs probably worth exploring other ways to archive your code.
Note. My example uses closure { self.count -= 1 } , where you can expect { self.count-- } . The latter does not work because the expression is with a value, so Swift will interpret it as a shorthand for the return value of the closure. He then complains that you have assigned a closure () -> Int to the property that is awaiting closure () -> () (aka Void -> Void ). Using -= 1 instead works around this issue.