2016-12-21 2 views
14

У меня есть подклассы UINavigationController и UITableViewController.Инициализация удобства подкласса UINavigationController делает подкласс постоянным init дважды

Чтобы инициализировать подклассы, я решил использовать некоторые методы convenience init, которые вызывают некоторый назначенный инициализатор суперкласса. Кроме того, каждый подкласс имеет некоторую константу let:

let someValue: SomeClass = SomeClass() 

Каждый класс успешно инициализирован, вызвав его вновь созданный convenience init метод.

Проблема заключается в том, что константа let инициализируется ДВАЖДЫ в UINavigationController подкласса.

import UIKit 
import PlaygroundSupport 

final class Navigation: UINavigationController { 
    convenience init(anyObject: Any) { 
     self.init(rootViewController: UIViewController()) 
    } 
    let service = Constant("Constant Initialization -> Navigation") 
} 

final class Table: UITableViewController { 
    convenience init(anyObject: Any) { 
     self.init(style: .plain) 
    } 
    let service = Constant("Constant Initialization -> Table") 
} 

class Constant: NSObject { 
    init(_ string: String) { 
     super.init() 
     debugPrint(string) 
    } 
} 

Navigation(anyObject: NSNull()) 
Table(anyObject: NSNull()) 

ли мы право использовать convenience init как выше? Зачем?

Почему поведение должно быть в следующих двух случаях: convenience init?

Проверено с: версии 8.2 бета (8C30a), версии 8.2 (8C38), Version 8.2.1 (8C1002)

P.S. Журнал игровых площадок приведенного выше кода:

"Constant Initialization -> Navigation" 
"Constant Initialization -> Navigation" 
"Constant Initialization -> Table" 

ответ

3

Так что это кажется странным «ожидаемым поведением» со Свифт. Причина, по которой это происходит, связана с постоянным инициализированным свойством service. А именно, это сообщение суммирует вопрос видя ваши довольно хорошо: blog post

По существу, Obj-C, лежащие в основе супер классы утечки памяти и ваши service свойства инициализируется дважды из-за этот шаблон инициализации Obj-C:

- (id)init { 
    self = [super init]; 
    if (self) { 
    self = [[self.class alloc] initWithNibName:nil bundle:nil]; 
    } 
    return self; 
} 

простое решение, чтобы избежать этого является следующая картина:

import UIKit 

final class NavigationController: UINavigationController { 
    var service: ObjectTest? 

    convenience init() { 
     self.init(rootViewController: UIViewController()) 
     self.service = ObjectTest("init nav") 
    } 
} 
class ObjectTest: NSObject{ 
    init(_ string: String) { 
     super.init() 
     print(string) 
    } 
} 

Все это меняется от вашей реализации инициализирует service только после того, как лет сам класс ur инициализируется.

Другим решением, однако, является использование назначенного инициализатора для инициализации суперкласса. Это означает, что вы не используете инициализатор удобства, который использовал бы описанную выше схему инициализации Obj-C.

+0

Благодарим вас за ответ. И я до сих пор не понимаю, почему в этих двух случаях поведение инициализации удобства отличается? – iWheelBuy

+0

Таким образом, инициализация 'удобство' использует приведенный выше примерный шаблон инициализации Objective-C, где есть два вызова init (' [super init] 'и' [self.class alloc] init ...] '. Назначенный инициализатор из моего понимая, попадет прямо в '[self.class alloc] init ...]' путь инициализации и поэтому не будет дважды инициализироваться, что и вызывает проблему, которую вы видите. – BHendricks

+0

Я думал, что в обоих случаях Я называю назначенный инициализатор, не так ли? – iWheelBuy

 Смежные вопросы

  • Нет связанных вопросов^_^