2016-02-13 61 views
8

我试图让我的头绕着团队,并将其剥离为基本实现。我想出了这个,但委托函数永远不会被调用。任何人都可以点亮一下吗?如何在Swift中完成委托的基本实现?

protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 
+0

您需要分配selfdelegate财产的重要性在继续调用之前将变量“委托”与DelegateClass相关联。在这种情况下,您将调用一个函数,而不是一个运行时错误的零值! – kandelvijaya

+0

委托与基于接口的对象组合类似。这是解耦对象和责任的一种方式。如果您阅读设计模式的Head First的前三章,您可能会更好地欣赏它。 – kandelvijaya

回答

1

DelegateClass一个实例都需要自己设定的DelegatorClass

因此一个实例的代表,你会是这样的:

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 

    func testFunction() { 
     var delegator=DelegatorClass() 
     delegator.delegate=self 
     delegator.callDelegate() 
    } 
} 
4

使用你的代码,这是方法正确使用委托。 当你调用callDelegate(),它会采取DelegateClass的参考,并执行delegatedFunction()

protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    let my_class= DelegatorClass() 
    my_class.delegate = self 

    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 

看看苹果的协议单证以获取更多信息。 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

+0

这给出了这些错误: let class = DelegatorClass()//关键字'class'不能用作标识符 class.delegate = self //预期声明 –

+1

ups,我的坏,我没有测试过,我会编辑该职位。 – UlyssesR

+0

太好了,谢谢。这行:“my_class.delegate = self”仍然给出预期的声明错误。任何想法为什么?该线应该在功能内吗? –

7
let myDelegatorObj = DelegatorClass() 
myDelegatorObj.delegate = DelegateClass() 
myDelegatorObj.callDelegate() 

点是在打电话之前callDelegate()您需要分配delegate。要检查您的委派工作,您可以使用委托初始化DelegatorClass

class DelegatorClass { 
    var delegate: MyDelegate? = DelegateClass() 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 
+2

这看起来像要走的路。不过,我会指定第一个示例和第二个示例是激活委派的不同方法。第一个例子是最通用的,因为它允许使用代理类的不同代码,而不需要在代理类中对其进行硬编码 –

+0

@MarcoPappalardo你是对的。第二个例子仅用于测试。 –

3

测试并在样品游乐场上工作。

import UIKit 

protocol MyDelegate { 
    func delegatedFunction(a: String) 
} 

class DelegatorClass { 

    var delegate: MyDelegate? 

    func callDelegate() { 
     delegate?.delegatedFunction("Hello World!") 
    } 
} 

class DelegateClass: MyDelegate { 

    let my_class = DelegatorClass() 

    init() { 
     my_class.delegate = self 
    } 

    // MyDelegate Protocol implementation 
    func delegatedFunction(a: String) { 
     print(a) 
    } 

} 

要测试它,请在下面添加以下几行。

let c = DelegateClass() 
c.my_class.callDelegate() 

讲解,

当您创建DelegateClass c的实例,它被初始化,执行init方法。 DelegatorClass实例my_class成员delegate现在持有对DelegateClass的self的引用。

现在执行callDelegate()方法时,由于在可选变量delegate现在保持对所述DelegateClass实例的引用,它基本上要求在它的delegatedFunction(a: String)方法的执行。因此,打印字符串a

另请注意,我必须将my_class.delegate = self放在init()之内的原因是因为您只能在类的方法之外拥有实例属性声明。所有的功能应该进入方法。

希望解释清楚! :)

-1
protocol Delegate{ 

    func callMe() 
    func textMe() 
} 

@objc protocol DelegateWithOptional: class{ 

    optional func callMe() 
    func textMe() 
} 

class SomeClass{ 

    var delegate: Delegate? 

    func call(){ 
     delegate?.callMe() 
    } 

    func text(){ 
     delegate?.textMe() 
    } 

} 

class SomeClass2{ 

    var delegateWithOptional: DelegateWithOptional? 

    func call(){ 
     delegateWithOptional?.callMe() 
    } 

    func text(){ 
     delegateWithOptional?.textMe() 
    } 
} 

class ClassConfirmingToProtocol: SuperClass, Delegate{ 

    var someClass = SomeClass() 
    override func viewDidLoad(){ 
     someclass.delegate = self 
    } 

    //must implement this method 
    func textMe(){ 
     //do something 
    } 

    //must implement this method 
    func callMe(){ 
     //do something 
    } 

} 

class ClassConfirmingToProtocolWithOptional: SuperClass, DelegateWithOptional{ 

    var someClass2 = SomeClass2() 
    override func viewDidLoad(){ 
     someclass2.delegate = self 
    } 

    //must implement this method 
    func textMe(){ 
     //do something 
    } 

    //optional to implement this method, i.e. even without this method, its not gonna throw any error 
    func callMe(){ 
     //do something 
    } 

} 
4
protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 
let delegator = DelegatorClass() 
delegator.callDelegate() // print nothing, because delegate is nil by default 

// set your delegate !!!!!!! 
delegator.delegate = DelegateClass() 
delegator.callDelegate() // print "hello" 

这是没有错的方法,只要使用正确的方式。关键是将委托变量设置为符合协议MyDelegate的类型T的某个实例。在你的情况下,这是DelegateClass实例。通常,T几乎可以符合MyDelegate协议的所有要求。

struct S:MyDelegate { 
    func delegatedFunction(a: String) { 
     print("Hello from struct conforming to MyDelegate protocol") 
    } 
} 

delegator.delegate = S() 
delegator.callDelegate() // print "Hello from struct conforming to MyDelegate protocol" 

delegator.delegate = nil 
delegator.callDelegate() // print nothing again :-) 
2

你近了吧,你根本都忘了给class DelegateClass分配给class DelegatorClassdelegate属性,与其他一些调整。

基本上,你告诉class DelegateClass符合protocol MyDelegate,这意味着它必须执行delegatedFunction(a:String)。在class DelegatorClass,在delegate属性被期待被分配一个类型的protocol MyDelegate的对象,以便它可以调用协议功能反对,因此在DelegateClass

protocol MyDelegate{ 
    func delegatedFunction(a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate! = nil 
    func callDelegate() { 
     delegate.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    var delegator:DelegatorClass = DelegatorClass() 

    init() { 
     delegator.delegate = self 
     delegator.callDelegate() 
    } 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
}