在Swift中委托单例类

8

如何使用单例/共享类的委托方法?有一个单例类定义了一些协议,但我不知道如何在其他类中访问委托函数。

参考代码片段(Swift):

protocol AClassDelegate
{
  func method1()
}

class A
{
   static let shared = A()

   override init() {
     //initialisation of member variables
   }

   var delegate: AClassDelegate
   func foo() {

   }
}


class B: AClassDelegate
{
   func bar() {
      // Note: not getting call to 'foo' method of class 'A'
      A.shared.delegate = self
      A.shared.foo()
   }
}

这个实现是否正确?


1
委托应始终为弱引用。 - Oleg Gordiichuk
2
你还应该在你的A类中添加一个私有的init()方法,以确保它始终作为单例使用。因为当前你也可以声明A(),这不会是一个单例。 - totiDev
建议:不要允许任何类(如B类)设置单例的委托。强烈建议在init()时传入单例使用的委托。您的单例调用委托的method1来完成某些任务。作为委托的B类不应该设置(或者真的调用)单例。 - Price Ringo
@Price,是的,你说得对!但我需要在整个应用程序中保留类“A”的一些数据/调用,并且还希望将数据委托给调用类,因此将其设置为单例。但是为了避免这个问题,我们可以使用推送通知来广播信息,而不是使用委托。对吗? - iTink
2个回答

14

首先,我想指出:

1- 创建一个单例类应该包含:

private init() {}

这导致只能通过使用该类的共享实例来访问它。

2-Max的答案所述,委托应为可选并具有弱引用

3- 协议应为class类型,如下所示:

protocol AClassDelegate: class

如果需要更多信息,您可以查看此Q&A


现在,为了测试目的,让我们假设当从A类调用foo()时应调用AClassDelegatemethod1()

protocol AClassDelegate: class {
    func method1()
}

class A {
    private init() {}
    static let shared = A()

    weak var delegate: AClassDelegate?

    func foo() {
        print(#function)

        delegate?.method1()
    }
}

让我们实现符合 AClassDelegate 的类:

class B: AClassDelegate {
    func bar() {
        A.shared.delegate = self
        A.shared.foo()
    }

    func method1() {
        print("calling the delegate method B Class")
    }
}

class C: AClassDelegate {
    func bar() {
        A.shared.delegate = self
        A.shared.foo()
    }

    func method1() {
        print("calling the delegate method C Class")
    }
}

输出应该是:

let b = B()
b.bar()
// this will print:
/*
 foo()
 calling the delegate method B Class
 */

let c = C()
c.bar()
// this will print:
/*
 foo()
 calling the delegate method C Class
 */

感谢Ahmed提供的逐步流程! - iTink

5

这几乎是正确的。但你忽略了单例对象永远存在(除非你在某处销毁它),但是它的委托可能不存在。为了避免崩溃,将 delegate 属性设置为 weak 和可选的。

weak var delegate: AClassDelegate?

这样你就不必关心委托是否存在了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接