什么时候我应该快速访问自己的属性?

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

class SpecialView: UIView { let backgroundLayer = CAShapeLayer() init() { backgroundLayer.backgroundColor = UIColor.greenColor().CGColor } } 

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

 class SpecialView: UIView { let backgroundLayer = CAShapeLayer() init() { var backgroundLayer = CALayer() backgroundLayer.backgroundColor = UIColor.greenColor().CGColor } } 

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

在Objective-C中,我总是避开ivars的属性,为了清晰起见,属性总是以自身为前缀。 我不必担心迅速的艾滋病,还有什么时候我应该快速使用自己的其他考虑?

我不相信除了具有相同名称的本地variables或closures内部以外,还有其他任何理由。 我个人更喜欢总是写“自我”,因为:

  1. 这是一个即时和明显的迹象,该variables是一个属性。 这是重要的,因为它是一个属性意味着它的状态可以变化更广泛和不同的方式比局部variables。 而且,改变一个属性比改变一个局部variables的含义更大。
  2. 如果您决定引入与属性名称相同的参数或variables,则不需要更新代码
  3. 代码可以很容易地复制进出自己需要的闭包

大多数时候我们可以跳过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) }) 
  2. 有一次我们应该使用它:所以你不要用class属性搞乱局部variables:

     class MyClass { var someVar: String = "class prop" func setProperty(someVar:String = "method attribute") -> () { print(self.someVar) // Output: class property print(someVar) // Output: method attribute } } 
  3. 我们可以使用self.其他地方self. 之前财产只是performance的variables/常量来自于。

正如苹果文档在https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html所说;

自己的财产

每个types的实例都有一个名为self的隐式属性,它与实例本身是完全等价的。 您可以使用self属性在自己的实例方法中引用当前实例。

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

 func increment() { self.count += 1 } 

在实践中,你不需要经常写自己的代码。 如果你没有明确地写自己,Swift假设你在方法中使用一个已知的属性或方法名称时,指的是当前实例的一个属性或方法。 Counter的三个实例方法中使用了count(而不是self.count)就可以certificate这个假设。

此规则的主要例外情况是:实例方法的参数名称与该实例的属性具有相同的名称。 在这种情况下,参数名称优先,有必要以更合适的方式引用该属性。 您可以使用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" 

没有自身的前缀,Swift会假设x的两个用法都引用了方法参数x。

每当我使用一个属性来忽略这些误解,我宁愿继续使用自己。

正如尼克所说,在Objective-C中,我们拥有ivars +综合属性,这些属性赋予_internalvariables名称来描述事物。 例如。

 @IBOutlet (nonatomic,strong) UITableView *myTableView; 

导致_myTableView (最好)内部引用 – self.myTableView被引用超越类。 虽然这是非常黑白的,但考虑一下以编程方式实例化视图时的例外,你可以通过移除自己来获得清晰/简单/减less样板。

 @interface CustomVC:UIViewController { UITableView *myTableView; } 

在迅速,公共/内部属性澄清这个范围。 如果这是一个公共财产,其他class级将与自己的错误互动。 否则,如果它是内部跳过自我,并避免自动重复。 编译器会在需要的时候抓到你。

 // UIViewcontroller swift header public var title: String? // Localized title for use by a parent controller. public var navigationItem: UINavigationItem { get } /// In your class self.title = "Clarity" self.navigationItem.leftBarButtonItem = UIBarButtonItem() // In superclass @property(nonatomic, copy) NSString *screenName // use self.screenName in swift subclass @IBOutlet myTableView:UITableView // use self public var myTableView:UITableView // use self internal var myTableView:UITableView // skip self var myTableView:UITableView // skip self