2015-03-11 2 views
0

У меня есть простой вопрос, что у меня проблемы с поиском ответа два. Код ниже сбой. От отладки, похоже, происходит из цикла, я думаю, это потому, что я ссылаюсь на другой класс в обоих классах. Может кто-нибудь объяснить, что происходит, и, если возможно, показать, как я могу поговорить обоим классам друг с другом (в обоих направлениях)? Любая помощь будет очень высоко ценится ! Спасибо.Как я могу ссылаться на экземпляры других классов в обоих направлениях без сбоев?

View Controller Один

import UIKit 

class ViewControllerOne: UIViewController{ 

    let doSomething = DoSomething() 
    var one = "test" 

    @IBAction func buttonTapped(sender: AnyObject) { 
     doSomething.functionTwo() 
    } 
} 

Do Something крэш

import UIKit 

class DoSomething: NSObject { 

    let viewControllerOne = ViewControllerOne() 

    func functionTwo() -> String{ 
     var two = viewControllerOne.one 
    return two 
    } 
} 

Do Something Это работает

import UIKit 

class DoSomething: NSObject { 


    func functionTwo() -> String{ 
     let viewControllerOne = ViewControllerOne() 

     var two = viewControllerOne.one 
    return two 
    } 
} 

ответ

1

В первом случае инициализатор DoSomething должен создать ViewControllerOne. Поскольку инициализатор ViewControllerOne создает DoSomething, они вращаются бесконечно. Во втором случае DoSomething не создается до тех пор, пока не вызывается functionTwo(), поэтому нет цикла. Вы можете их разговаривать друг с другом, например, таким образом:

import UIKit 

class ViewControllerOne : UIViewController 
{   
    let doSomething = DoSomething() 
    var one = "test" 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 
     doSomething.viewControllerOne = self  
    } 

    @IBAction func buttonTapped(sender: AnyObject) 
    { 
     doSomething.functionTwo() 
    } 
} 

class DoSomething: NSObject 
{  
    weak var viewControllerOne : ViewControllerOne? 

    func functionTwo() -> String 
    { 
     return viewControllerOne?.one ?? String() 
    } 
} 

-

Так вот как это работает ступенчато:

  1. ViewControllerOne создается, инициализатор по умолчанию называется. Он вызывает инициализаторы для doSomething = DoSomething() и var one = "test" (это равно String ("test")).
  2. Инициализатор по умолчанию DoSomething устанавливает необязательный viewControllerOne в nil
  3. Когда экземпляр ViewControllerOne завершен, вызывается вызов viewDidLoad. Он устанавливает для себя свойство doSomething.viewControllerOne.Это означает, что:
    • счетчик ссылок (используется для ARC) не увеличивается, это важно, потому что, если вы когда-либо решили удалить экземпляр ViewControllerOne, и doSomething будет иметь сильную ссылку на него, они никогда не получат удален ARC и вы потеряете модуля памяти
    • свойство ссылается на экземпляр вида, который имел viewDidLoad называется - self в Swift похож на this на других языках
  4. Когда functionTwo называется, его либо возвращает значение one или если viewControllerOne равно нулю, он возвращает пустую строку
+0

Спасибо, ваш ответ очень полезен. Это дало мне более глубокое понимание альтернатив. вы можете объяснить, как doSomething.viewControllerOne = self работает. кажется, «захватывает» DoSomething() и делает это сам? – KML

+0

Я отредактировал свой ответ, чтобы добавить подробности, надеюсь, что это поможет. Пожалуйста, отметьте мой ответ, если он – Krzak

+0

Спасибо, Krzak за подробный ответ - на самом деле это очень полезно - спасибо! – KML

0

Классы никогда не говорят. Это чертежи.

Вы имеете в виду экземпляры класса, которые должны общаться. Два способа: либо каждый экземпляр имеет ссылку на другой экземпляр , либо экземпляры отправляют сообщения третьему объекту, который действует как почтмейстер. См. NSNotification для получения подробной информации о том, как общаться в приложениях, не зная других объектов по ссылке.

+0

Но, как я понимаю, я обращаюсь к ViewControllerOne в DoSomething с помощью viewControllerOne = ViewControllerOne(). Почему это работает во втором примере и сбой в первом. Как я могу ссылаться на ViewControllerOne() один раз, а затем ссылаться на него позже.? – KML

+0

DoSomething создает на init экземпляр ViewControllerOne. ViewControllerOne создает в своем init экземпляр DoSomething. Loop forever> crash. Создайте третий класс, который будет создавать классы стендов и хранить ссылки классов в другом и наоборот. Таким образом, каждый класс может разговаривать с другим. –

+0

Правильно, так как бы вы решили это? Можете ли вы, например, объяснить, что такое почтмейстер? – KML

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