2015-11-09 2 views
1

Я пытаюсь создать пользовательский UIView и потеряться до завершения инициализации.Свойства инициализации в Swift 2

Код Один

class CustomUIView: UIView { 
    var propertyToInitialize: CGRect 

    //Custom Initializer 
    override init(frame: CGRect) { 
     self.propertyToInitialize = CGRect(x: 0, y: 0, width: (superview?.frame.size.width)!, height: (superview?.frame.size.height)!) 
     super.init(frame: frame) 
    } 
} 

Когда я использую приведенный выше код XCode ошибка дает мне следующим образом.

Ошибка

Use of 'self' property access 'superview' before super.init initializes self 

Так я изменил мой код

Код Два

class CustomUIView: UIView { 
    var propertyToInitialize: CGRect 

    //Custom Initializer 
    override init(frame: CGRect) { 
     self.propertyToInitialize = CGRect() 
     super.init(frame: frame) 
     self.propertyToInitialize = CGRect(x: 0, y: 0, width: (superview?.frame.size.width)!, height: (superview?.frame.size.height)!) 
    } 
} 

Вопрос

Это плохой дизайн? Должен ли я придерживаться другого подхода? Я инициализирую свойство дважды, поэтому, используя больше памяти?

ответ

2

Все это плохой дизайн. Сделайте propertyToInitialize необязательной упаковкой CGRect, так что ей не нужно значение во время инициализации и переместите свой код в didMoveToSuperview вашего представления, что является первым моментом, когда концепция супервизора имеет какое-либо значение. Еще лучше, не делайте это свойством вообще; надсмотр может быть рассмотрен в любое время, когда вам нужна эта информация, поэтому бессмысленно дублировать его в свойстве.

+0

Спасибо за ответ. Я считаю, что лучший подход для меня - необязательный. Разве нет свойства типа «Lazy» в swift, которое позволяет вам сразу же установить свойство? –

+0

Да, есть. Или вы можете использовать вычисленное свойство, чтобы эта вещь _looks_ как свойство, но на самом деле является функцией, которая рассматривает супервизор в режиме реального времени. – matt

0

Прежде чем вы сможете получить доступ к любым объектам в self, вам необходимо позвонить super.init и поместить его в совершенно другую функцию.

class CustomUIView: UIView { 
    var propertyToInitialize: CGRect? 

    init(frame: CGRect, property: CGRect) { 
     super.init(frame: frame) 
     self.propertyToInitialize = property 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     //Decode propertyToInitialize 
    } 
} 
+0

Это не скомпилировано. Попробуй. – matt

+0

@matt Я этого не осознавал, извините. Я просто обновляю свой код. – kabiroberai

+0

@matt Я только что обновил свой код. Надеюсь, все работает сейчас :) – kabiroberai

1

Я нашел лучший подход для меня был.

Код

class CustomUIView: UIView { 
    lazy var propertyToInitialize: CGRect = self.initializeProperty() 

    //Custom Initializer 
    override init(frame: CGRect) { 
     super.init(frame: frame) 
    } 

    func initializeProperty() -> CGRect { 
     let rect: CGRect = CGRect(x: 0, y: 0, width: (superview?.frame.size.width)!, height: (superview?.frame.size.height)!) 
     return rect 
    } 
} 

Я думаю, что это лучший ответ, потому что я не использую свойство, пока она не понадобится. И, все еще можно получить размер супервизора, но не обязательно double initialize.