Why can't I access self?
So you want to subclass from UIView.
You could use the concrete class instead of Self. Self would only be relevant for subclassing, when you do not want to override. Using CustomView instead of Self makes many things easier.
You could use one class method instead of two.
You could override a init method, instead of this customizing method.
But if you really need it that way, here is a working solution:
import UIKit
public class CustomView: UIView {
public var property: Int = 0
public required override init(frame: CGRect) {
super.init(frame: CGRectZero)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public class func createCustomView(param: Int) -> Self {
return createCustomViewInternal(param)
}
private class func createCustomViewInternal(param: Int) -> Self {
return self.init(frame: CGRectZero).createCustomViewInstance(param)
}
private func createCustomViewInstance(param: Int) -> Self {
self.property = param
return self
}
}
Side note:
Arguments are the concrete given values. When you use the abstract value in a method, it is called parameters.
self is not available in swift project
All the code after the closing brace for your featureprintObservationForImage
function is not inside any function or closure. You can't do that. (That code is not just variable decalrations. You have function calls, which is not legal outside of a function.)
You can create something called computed properties, where you provide a closure that gets invoked each time you read a value from the property.
Is there a tangible benefit to using self outside of closures?
There is.
In the examples you provided it makes no difference, it's purely a style choice. Some people might like it since it explicitly tells you you're modifying self
, personally I think it looks cleaner without.
Where it matters is when you have a local variable with the same name. Let's say you have a class that has a var count: Int
property. Then, in one of your methods, you declare a new variable with the same name.
The local variable will be used whenever you type count
, so if you want to modify or read the object's variable, you'll need to use self
.
Some examples where it makes a difference:
guard let count = calculateCount() as? Int else { return }
self.count = count
init(count: Int) {
self.count = count
}
func updateCount(_ count: Int) {
self.count = count
}
What is the purpose of self in Swift
self
is a reference to the current instance of the class in which the code is running.
In both the init
method and the paint
method, it allows you to specify that you wish to set the member variable named color
using the value passed in the parameter to the method that is also called color
.
The paint
method cannot reference the parameter passed to init
at all (nor vice versa).
So, in your sample code, both methods set the color
of the object to some specified value passed in to the method as a parameter.
The init
method sets an initial color for the object.
The paint
method then allows you to change the color of the object from that initial color.
This might be clearer if the parameters were simply named differently, e.g.:
required init(initialMake: String, initialColor: String) {
self.make = initialMake
self.color = initialColor
}
func paint(newColor: String) {
self.color = newColor
}
In this case, since the functions are member methods, the self
is now entirely optional since the compiler knows that color
now can only mean the member called color
since there is no other variable or parameter with that name, i.e. the paint
method could be written simply as:
func paint(newColor: String) {
color = newColor
}
and this would have the exact same behaviour.
However, some people prefer to keep the self
prefix for clarity, even where it isn't strictly required since as well as making the intent clear it can help avoid accidental mistakes if variables or member names are changed.
What is self used for in Swift?
You will also use self a lot when creating your extensions, example:
extension Int {
func square() -> Int {
return self * self
}
// note: when adding mutating in front of it we don't need to specify the return type
// and instead of "return " whatever
// we have to use "self = " whatever
mutating func squareMe() {
self = self * self
}
}
let x = 3
let y = x.square()
println(x) // 3
printlx(y) // 9
now lets say you want to change the var result itself
you have to use the mutating func to make change itself
var z = 3
println(z) // 3
now lets mutate it
z.squareMe()
println(z) // 9
// now lets see another example using strings :
extension String {
func x(times:Int) -> String {
var result = ""
if times > 0 {
for index in 1...times{
result += self
}
return result
}
return ""
}
// note: when adding mutating in front of it we don't need to specify the return type
// and instead of "return " whatever
// we have to use "self = " whatever
mutating func replicateMe(times:Int){
if times > 1 {
let myString = self
for index in 1...times-1{
self = self + myString
}
} else {
if times != 1 {
self = ""
}
}
}
}
var myString1 = "Abc"
let myString2 = myString1.x(2)
println(myString1) // "Abc"
println(myString2) // "AbcAbc"
now lets change myString1
myString1.replicateMe(3)
println(myString1) // "AbcAbcAbc"
Initialising member to class function causes 'self' used in method call error
It might be better to not use a Bool
, but rather a nested Enum
, which is also more extendible if you wanna add some other modes of haptic feedback later on.
I have a generalized solution for a generalized problem of your question. So either you do:
public class FunctionOwner {
private let mode: Mode
public init(`do` mode: Mode = .default) {
self.mode = mode
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
switch mode {
case .foo: foo()
case .bar: bar()
}
}
}
private extension FunctionOwner {
func foo() {
print("doing foo")
}
func bar() {
print("doing bar")
}
}
public extension FunctionOwner.Mode {
static var `default`: FunctionOwner.Mode {
return .foo
}
}
// USAGE
FunctionOwner(do: .bar).fooOrBar() // prints "doing foo"
FunctionOwner(do: .foo).fooOrBar() // prints "doing bar"
Or if you for some reason do want to keep the stored Mode
, you can do this (might be relevant for your actual question on how you do a workaround of referencing self
in the init.):
public class FunctionOwner {
private let _function: (FunctionOwner) -> Void
public init(`do` mode: Mode = .default) {
_function = { functionOwner in
switch mode {
case .foo: functionOwner.foo()
case .bar: functionOwner.bar()
}
}
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
_function(self)
}
}
// The rest of the code is the same as the example above
Swift - Function as Variable with Self Reference
Change your action definitions to use a capture group:
action: {
[weak self] in
guard let strongSelf = self else {
return
}
strongSelf.doSomething()
}
What the [weak self]
capture group declaration does is to convert self to a weak variable inside the block. If the owning object gets deallocated while the block is waiting to be called it gets passed nil instead.
Then once inside the block the guard statement tries to map the weak self definition to a strong local variable. If self is nil, it exits. If not, strongSelf contains an unwrapped strong reference to self and you proceed as normal.
Related Topics
How to Unwrap Arbitrarily Deeply Nested Optionals in Swift
Swiftui - How to Get Coordinate/Position of Clicked Button
Formula to Pick Every Pixel in a Bitmap Without Repeating
When to Call Activatesession() on Wcsession Object
How to Set an Initial Value for @Nsmanaged Property Pfobject Subclass
Realmswift Initialize List:Cannot Specialize a Non-Generic Definition
Easiest Way to Increment a Data Point in Firebase
How to Set iOS 13 Glyphs Programmatically
No Such Module Jsqmessagesviewcontroller
Using 'If-Case' Format in Boolean Assignment in Swift
Zposition of Sknode Relative to Its Parent
Uitableviewautomaticdimension Not Working on iOS 8
Animate Path Stroke Drawing in Swiftui
Generic and (Early) Binding in Swift 1.2