2016-02-13 42 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) 
    } 
}