Подтвердить что ты не робот

Когда мне нужно быстро получить доступ к свойствам с помощью self?

В простом примере, например, я могу опустить self для ссылки на backgroundLayer, потому что он однозначно определяет, какой backgroundLayer установлен в backgroundColor.

class SpecialView: UIView {
    let backgroundLayer = CAShapeLayer()

    init() {
        backgroundLayer.backgroundColor = UIColor.greenColor().CGColor
    }
}

Но, как и в Objective-C, мы можем путать вещи, добавив локальные переменные (или константы), названные аналогично. Теперь backgroundColor устанавливается на неформатный слой:

class SpecialView: UIView {
    let backgroundLayer = CAShapeLayer()

    init() {
        var backgroundLayer = CALayer()

        backgroundLayer.backgroundColor = UIColor.greenColor().CGColor
    }
}

(это разрешается с помощью self.backgroundLayer.backgroundColor)

В Objective-C я всегда избегал ivars для свойств, и свойства всегда были префиксом self для ясности. Мне не нужно беспокоиться об иварах в быстром, но есть ли другие соображения, когда я должен использовать себя в быстрой?

4b9b3361

Ответ 1

Единственный раз, когда требуется self, это когда ссылка на свойство внутри замыкания и, как вы указали, отличают его от локальной переменной с тем же именем.

Однако лично я предпочитаю всегда писать "я", потому что:

  1. Это мгновенный и очевидный признак того, что переменная является свойством. Это важно, потому что это свойство означает, что его состояние может изменяться более широко и по-разному, чем локальная переменная. Кроме того, изменение свойства имеет более серьезные последствия, чем изменение локальной переменной.
  2. Код не нужно обновлять, если вы решили ввести параметр или переменную с тем же именем, что и у свойства
  3. .Код может быть легко скопирован в и из замыканий, которые требуют себя

Ответ 2

В большинстве случаев мы можем пропустить self. при доступе к свойствам класса.

  • Однако есть один раз, когда мы ДОЛЖНЫ использовать его: когда мы пытаемся установить self.property в замыкание:

    dispatch_async(dispatch_get_main_queue(), {
        // we cannot assign to properties of self
        self.view = nil 
    
        // but can access properties
        someFunc(view)
    })
    
  • один раз, когда мы ДОЛЖНЫ использовать его: поэтому вы не испортите локальную переменную со свойством класса:

    class MyClass {
        var someVar: String = "class prop"
    
        func setProperty(someVar:String = "method attribute") -> () {
            print(self.someVar) // Output: class property
            print(someVar) // Output: method attribute
        }
    }
    
  • другие места, где мы CAN используем self. прежде чем свойство, чтобы быть выразительным, были переменными/константами.

Ответ 3

Глядя на руководство по стилю Рэя Вендерлиха

Use of Self

Для краткости избегайте использования self, поскольку Swift не требует, чтобы он обращался к свойствам объекта или вызывал его методы.

Используйте self только тогда, когда это требуется компилятором (в замыканиях @escaping или в инициализаторах для устранения неоднозначности свойств по аргументам). Другими словами, если он компилируется без self, тогда опустите его.

Документация Swift дает такую же рекомендацию.

The self Property

Каждый экземпляр типа имеет неявное свойство, называемое self, которое в точности эквивалентно самому экземпляру. Свойство self используется для ссылки на текущий экземпляр в его собственных методах экземпляра.

Метод increment() в приведенном выше примере можно было бы написать так:

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

На практике вам не нужно очень часто писать self в своем коде. Если вы не пишете self явно, Swift предполагает, что вы ссылаетесь на свойство или метод текущего экземпляра всякий раз, когда вы используете известное имя свойства или метода в метод. Это предположение демонстрируется использованием count (а не self.count) внутри трех методов экземпляра для Counter.

Основное исключение из этого правила возникает, когда имя параметра для метода экземпляра имеет то же имя, что и свойство этого экземпляра. В этой ситуации имя параметра имеет приоритет, и возникает необходимость обратиться к свойству в более квалифицированным способом. Свойство 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"

Ответ 4

Как говорится в документации Apple в https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html

Свойство

Каждый экземпляр типа имеет неявное свойство, называемое self, которое точно эквивалентен самому экземпляру. Вы используете свойство ссылаться на текущий экземпляр в своем собственном экземпляре Методы.

Метод increment() в приведенном выше примере может быть написан например:

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

На практике вам не нужно писать себя в свой код очень часто. Если вы явно не пишете себя, Свифт предполагает, что вы ссылаетесь к свойству или методу текущего экземпляра всякий раз, когда вы используете известное свойство или имя метода в рамках метода. Это предположение демонстрируется использованием count (а не self.count) внутри три метода экземпляра для счетчика.

Основное исключение для этого правила возникает, когда имя параметра для метод экземпляра имеет то же имя, что и свойство этого экземпляра. В в этой ситуации имя параметра имеет приоритет, и оно становится необходимо ссылаться на имущество более квалифицированным образом. Ты используешь свойство 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.

Я бы предпочел продолжать использовать self, когда я использую свойство, чтобы опустить эти недоразумения.

Ответ 5

Я собираюсь пойти против течения и не использовать self, если это абсолютно не требуется.

Причина в том, что две из основных причин использовать self это

  • При захвате self в блоке
  • При настройке self в качестве делегата

В обоих случаях self будет считаться ссылкой strong. Это может быть то, что вы хотите, но во многих случаях вы действительно хотите использовать weak.

Таким образом, принуждение разработчика использовать self в качестве исключения, а не правила сделает этот захват strong более осознанным и позволит ему обдумать это решение.

Ответ 6

Как сказал Ник, в objective-c у нас были ivars + синтезированные свойства, которые давали именам внутренних переменных, чтобы очерчивать вещи. Например.

@IBOutlet (nonatomic,strong) UITableView *myTableView;

в результате чего _myTableView должно быть (желательно) указано внутри - и self.myTableView для ссылки за пределами класса. В то время как это довольно черно-белое, рассмотрите исключение при программном создании представлений, вы можете получить четкость/простоту/уменьшить шаблон, удалив себя.

@interface CustomVC:UIViewController
{
     UITableView *myTableView; 
}

В быстром, общедоступные/внутренние свойства уточняют эту область. Если это публичное свойство, которое другие классы будут взаимодействовать с ошибкой на себе. В противном случае, если он внутренне пропустит сам себя и избежит автоматического повторения. Компилятор поймает вас, когда это будет необходимо.

// 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