Why Can't I Use Self in a Func Swift

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



Leave a reply



Submit