Distinction in Swift between uppercase Self and lowercase self
Self
refers to the type of the current "thing" inside of a protocol (whatever is conforming to the protocol). For an example of its use, see Protocol func returning Self.
The official docs I've found for Self
is in Protocol Associated Type Declaration in The Swift Programming Language. It surprisingly is not documented in the sections on protocols or on nested types:
However, now there is a paragraph about Self Type
including a code example in the official Swift Programming Language's chapter about Types
How can I invoke a method on `Self` in a Swift extension?
Since allZeros is already a method of Int you can just do it like this:
extension Int {
static var allOnes: Int { return ~allZeros }
}
Why this code capturing self inside this block compile in swift?
The compiler has never complained about this. But it should (and I have filed a bug on this point), because the code you've written won't work: the button will not actually do anything when tapped. (The app might even crash, but then again it might not.)
The reason (for both phenomena) is that the compiler misinterprets the term self
here to mean the class — which does exist before initialization of the instance.
The solution is to replace let
by lazy var
. That does work, because now the code will not actually be called until some later, when the instance does exist.
Better way of using self. in background thread?
You can create a nested function or another method to put the code you want to execute in, then pass that nested function or method into DispatchQueue.main.async
.
Here's an example with a nested function:
Original code:
class Foo {
var a = 0
var b = 0
var c = 0
func f() {
a = 1
b = 1
c = 1
}
}
Doing it asynchronously:
class Foo {
var a = 0
var b = 0
var c = 0
func f() {
func doAsync() {
a = 1
b = 1
c = 1
}
DispatchQueue.global(qos: .background).async(execute: doAsync)
}
}
As you can see, you don't need to add any self
s.
The type of self in Swift and its use with respect to two-phase initialization
1)
Shouldn't I get a compiler error if I'm trying to use self
too soon?
I do agree. You may send a bug report to swift.org.
Why does the compiler allow us to use self
here if self
is not ready to be used?
Unfortunately, there's another self
in the descendants of NSObject
, the method self()
of NSObject
.
2)
What is that and why does self have two different types within the same class?
The current Swift interprets the initial value expression in the class
context, not in the instance context.
You know method names can be used as closures in Swift:
class ViewController: UIViewController {
//..
func aMethod() {
//...
}
func anInstanceMethod() {
let meth = aMethod // () -> ()
}
}
Swift can also refer to an instance method in the class
context, which generates a so-called unapplied method reference (see SE-0042), which currently returns a curried function:
class ViewController: UIViewController {
//...
func aMethod() {
//...
}
class func aClassMethod() {
let meth = aMethod // (ViewController) -> () -> ()
}
}
The method self()
as well.
Generally we do not need self()
method and this behavior should be changed, I think.
How associated(typealias) type and Self in protocols work?
Pro1
Writing this
protocol Pro1 {
typealias Element
}
you are just telling that there will be a type named Element
.
Pro2
Adding this
protocol Pro2: Pro1 {
typealias Element = Self
}
you are telling to the compiler that Element
will be the same type of the type that is implementing Pro2
.
So yes, there is a relation between the Element
in Pro1
and Pro2
.
Adding methods to Pro1
Let's declare 2 methods that will use Element
in Pro1
protocol Pro1 {
typealias Element
func a() -> Element
func b(elm: Element)
}
Conforming to Pro1
Now a class conform to Pro1
will be like this.
class Foo: Pro1 {
func a() -> String {
return ""
}
func b(elm: String) {
}
}
As you can see we are forced by the compiler to set the return type of a
and the param of b
to be of the same type.
Conforming to Pro2
Now let's try to conform another class to Pro2. Again Pro1
will force us to declare methods a
and b
where the return type of a is equals to the param of b
.
Furthermore Pro2
will force us to set this type equals to the type of the current type Boo
.
So the previous class will to conform to Pro2
because String
is different from Foo
class Foo: Pro2 {
func a() -> String { // <- compiler error
return ""
}
func b(elm: String) { // <- compiler error
}
}
But if we declare a new class and replace Element
with Boo
it will work because the constraints of both protocols are satisfied.
class Boo: Pro2 {
func a() -> Boo {
return Boo()
}
func b(elm: Boo) {
}
}
Cannot assign to property: 'self' is immutable swift error
Make the protocol become reference type
protocol Positions: AnyObject {
Related Topics
Function Does Not Wait Until the Data Is Downloaded
Is Swift Dictionary of Indexed for Performance? Even for Exotic Types (Uuid)
Swift 2.0: Protocol Extensions: Two Protocols with the Same Function Signature Compile Error
Nsimage to Nsdata as Png Swift
Transparent Background for Texteditor in Swiftui
Trying to Know When a Window Closes in a MACos Document Based Application
Swift Setter Causing Exc_Bad_Access
Swift Dictionary Default Value
Stop a Dispatchqueue That Is Running on the Main Thread
Handling Multiple Gesturerecognizers
Swift Imagepickercontroller Didfinishpickingmediawithinfo Not Fired
Using Combine's Future to Replicate Async Await in Swift
How to Make an Array of the Current Week Dates Swift
Implicitly Unwrapped Optional Made Immutable
Where Is Info.Plist in Xcode 13? (Missing, Not Inside Project Navigator)