2017-02-03 152 views
-2

我创建了BaseClassviewController,我的所有控制器都是从此控制器派生的。我正在执行以下步骤:iOS中的功能覆盖

  1. BaseClassViewController中设置自定义代理。
  2. 执行协议的所有功能BaseClassViewController
  3. 然后我推HomeController派生自BaseClassViewController
  4. 再次我推DetailController也衍生自BaseClassViewController

现在,当委托函数被调用时,我应该得到在DetailController控制,但我得到控制在HomeController

所以我的问题是为什么它不在导航上调用顶级控制器,例如DetailController,是否可以在两个控制器中调用委托函数?

P.S我重写了所有子控制器中的委托函数。

编辑:在阅读答案和评论后,我想我没有清楚这么多,所以添加下面的代码片段。

在助手类:

@objc protocol SampleDelegate: class 
{ 
    @objc optional func shouldCallDelegateMethod() 
} 

class SampleHelper: NSObject 
{ 
    var sampleDelegate:SampleDelegate! 
    static var sharedInstance = SampleHelper() 

    //It is triggered 
    func triggerDelegateMethod() 
    { 
    sampleDelegate!.shouldCallDelegateMethod() 
    } 

    func apiCall() 
    { 
     let urlString = URL(string: "https://google.com") 
     if let url = urlString { 
     let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
     if error != nil { 
     print(error) 
     } else { 
     if let usableData = data { 
      self. triggerDelegateMethod() 
      } 
     } 
     } 
     task.resume() 
    } 
    } 
} 

在BaseClass的

class BaseClassViewController: UIViewController,SampleDelegate{ 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func viewWillAppear(_ animated: Bool) 
    { 
     super.viewWillAppear(true) 
     SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() 
    { 
     //Override 
    } 


} 

在HomeController的即第一控制器被推

class HomeViewController: BaseClassViewController{ 

     override func shouldCallDelegateMethod() 
     { 
      // 
     } 
} 

在DetailController即第二控制器从HomeController中的HomeController后推。

class DetailViewController: BaseClassViewController{ 
     override func viewDidLoad() 
     { 
      super.viewDidLoad() 
      SampleHelper.sharedInstance.apiCall() 
     } 
     override func shouldCallDelegateMethod() 
     { 
      // 
     } 
} 

现在我的问题是,当代表从辅助类触发它调用HomeViewControllershouldCallDelegateMethod但不是在DetailViewController。但DetailViewController位于导航数组的顶部。

还有什么可能,我可以触发相同的功能,在两个控制器一次只有委托?

+0

请分享你的声明和覆盖代表的代码片段。 – Aamir

+0

它以相当大的代码显示在这里以建设性的方式。但我想我已经在概念上以体面的方式解释了它。 –

+0

@Aamir如果你需要任何具体的东西让我知道我可以解释。 –

回答

0

BaseClassviewController你应该有一个delegate变量/财产。

HomeControllerDetailController你需要,如果你想这个类是听委托回调来设置delegate变量/属性self

0

编辑2

后您发布您的代码,我知道你已经使用了代表团的单例类。

代表允许对象发送消息到另一个对象。

答案为您的查询为“否”。委托人一次不能在两个控制器中触发相同的功能。

如果你真的想一次听两门课的活动,我建议你使用NSNotificationCenter而不是委托。

+0

Write SampleHelper.sharedInstance.delegate = self;在viewVilla中的homeVC方法和DetailVC方法。 – Mahesh

+0

然后它击败了子类的目的,并且我覆盖了所有子类中的方法.. –

0

最基本的问题是你正在使用委托与单身。

设置代理viewWillAppear也不是一个好的解决方案。简而言之,当视图控制器被显示和隐藏时,单例中的代理将一直在改变。

请勿使用单例代理。使用完成回调。否则,你会不断遇到问题。

func apiCall(onCompletion: (() -> Void)?) { 
    let urlString = URL(string: "https://google.com") 
    if let url = urlString { 
     let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
      if error != nil { 
       print(error) 
      } else if let usableData = data { 
       onCompletion?() 
      } 
     } 

     task.resume() 
    } 
} 

称为

SampleHelper.apiCall { 
    // do something 
} 
+0

我同意你的观点,但它仍然没有回答我的问题,为什么它没有在Home Controller中调用func。 –

+0

此外,如果你可以详细阐述一点,以详细解决你的问题将有所帮助.. –

+0

但是这个委托可以从同一类中的多个地方调用..例如createGroup for XMPP ..在这种情况下,我可以获得API响应以及通知该组已创建,以及我可以通过XMPP接收消息..所以我必须更新控制器来更新他们的用户界面。 –

-1

那不是正确的方法来实现这一目标。我认为适当的方式来设置代理只在各自的UIViewController,而不是在BaseViewController上实现该协议,然后在子类中重写。所以你的实现应该是这样的。

在HomeViewController

class HomeViewController: BaseClassViewController { 

    override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(true) 
    SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() { 
    // Provide implementation 
    } 

} 

在DetailViewController

class DetailViewController: BaseClassViewController { 

    override func viewWillAppear(_ animated: Bool) { 
    super.viewDidLoad() 
    SampleHelper.sharedInstance.delegate = self; 
    } 

    func shouldCallDelegateMethod() { 
    // Provide implementation 
    } 

} 

使用此imeplementation你将只一到一个通信设计模式有,以确保正确的UIViewController被调用。

+0

那么为什么这是不正确的方式? –

+0

因为我们通过在'BaseViewController'中实现协议来提高间接性,我们应该直接在相应的ViewController中实现。 – Aamir

+0

但我需要在不同的控制器中实现它。我无法得到它为什么会添加间接级别,因为委托总是分配给BaseClassViewController,我们只是重写这些函数。 –