我什么时候应该在swift中使用self访问属性?

Nic*_*ick 49 swift

在这样一个简单的例子中,我可以省略self来引用backgroundLayer,因为它明确设置了backgroundColor的backgroundLayer.

class SpecialView: UIView {
    let backgroundLayer = CAShapeLayer()

    init() {
        backgroundLayer.backgroundColor = UIColor.greenColor().CGColor
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,就像在Objective-C中一样,我们可以通过添加名称相似的局部变量(或常量)来混淆事物.现在,backgroundColor正在非形状图层上设置:

class SpecialView: UIView {
    let backgroundLayer = CAShapeLayer()

    init() {
        var backgroundLayer = CALayer()

        backgroundLayer.backgroundColor = UIColor.greenColor().CGColor
    }
}
Run Code Online (Sandbox Code Playgroud)

(这是通过使用self.backgroundLayer.backgroundColor解决的)

在Objective-C中,我始终避免使用ivars来获取属性和属性,为了清晰起见,它们总是以self为前缀.我不必担心快速的ivars,但是我应该在swift中使用self时还有其他考虑因素吗?

dre*_*wag 82

唯一self需要的是在引用闭包内的属性时,正如您所指出的那样,将它与具有相同名称的局部变量区分开来.

但是,就个人而言,我更喜欢总是写"自我",因为:

  1. 这是变量是属性的一个即时且明显的标志.这很重要,因为它是一个属性意味着它的状态可以比局部变量更广泛地以不同的方式变化.此外,更改属性比更改局部变量具有更大的含义.
  2. 如果您决定引入与属性同名的参数或变量,则不需要更新代码
  3. 代码可以轻松地复制进出需要自我的闭包

  • 我喜欢*不*使用self的原因是当闭包捕获强制你使用self时,它会突出(这很好,因为在闭包中引用self会保留它,与其他上下文不同,所以你希望它看起来"不同" ") (12认同)
  • 我认为不使用`self`可以使代码简洁明了.在使用属性编写公式时尤其如此.并且由于Xcode 7的语法着色,非常清楚哪些变量是本地的,哪些是属性. (10认同)
  • @NateCook我实际上向Apple提交了一个关于自我要求的错误,如果你同意我鼓励你也这样做:) (8认同)
  • 我同意所有观点。在某种程度上,这归结为个人设计品味,但在大多数情况下,清晰总比简洁好。 (2认同)

Kee*_*nle 18

大多数情况下,self.当我们访问类属性时,我们可以跳过.

  1. 但是有一次我们必须使用它:当我们尝试设置self.property一个闭包时:

    dispatch_async(dispatch_get_main_queue(), {
        // we cannot assign to properties of self
        self.view = nil 
    
        // but can access properties
        someFunc(view)
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. 有一次我们应该使用它:所以你不要使用class属性混淆局部变量:

    class MyClass {
        var someVar: String = "class prop"
    
        func setProperty(someVar:String = "method attribute") -> () {
            print(self.someVar) // Output: class property
            print(someVar) // Output: method attribute
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 其他地方,我们CANself. 刚需购房前表现大约是可变/恒定的来源.


Ant*_*tzi 7

我将逆流而上,self除非绝对需要,否则不会使用。

使用的两个主要原因self

  • self在块中捕获时
  • 设置self为代理人时

在这两种情况下,self都会被捕获作为strong参考。这可能是您想要的,但在许多情况下,您实际上想要使用一个weak

因此,强迫开发者将其self作为例外而不是规则来使用,会让这种strong捕获更有意识,并让他反思这个决定。


Doe*_*ata 6

查看Ray Wenderlich的风格指南

自我的运用

为简洁起见,请避免使用self,因为Swift不需要它访问对象的属性或调用其方法。

仅在编译器需要时使用self(在@escaping闭包中,或在初始化程序中从参数中消除属性歧义)。换句话说,如果它在没有自我的情况下编译,那么就忽略它。

Swift文档提出了相同的建议。

自我财产

一个类型的每个实例都有一个称为self的隐式属性,它与该实例本身完全等效。您可以使用self属性在其自己的实例方法中引用当前实例。

increment()上面示例中的方法可能是这样编写的:

func increment() {
    self.count += 1
}
Run Code Online (Sandbox Code Playgroud)

实际上,您不需要经常在代码中编写self。如果您没有显式地编写self,则Swift会假设您在方法中使用已知的属性或方法名称时,都在引用当前实例的属性或方法。通过在Counter的三个实例方法中使用count(而不是self.count)证明了这一假设。

当实例方法的参数名称与该实例的属性名称相同时,将发生此规则的主要例外。在这种情况下,参数名称优先,因此有必要以更限定的方式引用该属性。您可以使用self属性来区分参数名称和属性名称。

在此,self消除了在方法参数x和实例属性x之间的歧义:

struct Point {
    var x = 0.0, y = 0.0

    func isToTheRightOf(x: Double) -> Bool {
        return self.x > x
    }
}

let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
    print("This point is to the right of the line where x == 1.0")
}

// Prints "This point is to the right of the line where x == 1.0"
Run Code Online (Sandbox Code Playgroud)