2014-06-13 2 views
4

Swift를 사용하여 객체의 위임에 액세스하는 Objective-C 패턴을 에뮬레이션하려고합니다. 일반적으로 두 UIViewControllers간에 공유되는 .h 프로토콜을 넣을 것입니다.Swift를 통해 대리인에게 액세스하는 적절한 방법은 무엇입니까?

용도 : 대리자 (호스트)를 호출하여 (푸시) UIViewController를 닫습니다.
문제점 : 대리인의 hello()에 액세스 할 수 없습니다.

다음 코드는 컴파일되지만 실행시 오류가 발생합니다. 알 수없는 위임 방법 (아래 참조).

호스트/호출 (위임) 대상 :

import UIKit 

class MainViewController: UIViewController, ProtocolNameDelegate {      
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 
    // --------------------------------------------------------------------------------------------------------------- 
    // Protocol Delegate 

    func hello() { 
     println("Hello"); 
    } 

    // --------------------------------------------------------------------------------------------------------------- 

    @IBAction func greenAction(sender : AnyObject) { 
     let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("GreenViewController") as GreenViewController 
     secondViewController.delegate = self; 
     self.presentViewController(secondViewController, animated: true, completion: nil) 
    } 

    // --------------------------------------------------------------------------------------------------------------- 

    @IBAction func exitAction(sender : AnyObject) { 
     exit(0) 
    } 

기각하는 것입니다 밀어 (초 '녹색')의 UIViewController :

import UIKit 

@class_protocol protocol ProtocolNameDelegate { 
    func hello() 
} 

class GreenViewController: UIViewController { 
    weak var delegate: ProtocolNameDelegate? 

    // --------------------------------------------------------------------------------------------------------------- 

    @IBAction func returnAction(sender : UIBarButtonItem) { 
     println("Inside returnAction") 
     delegate?.hello() 
    } 
} 

수정 : 수정 대리인 액세스를 to : delegate? .hello() ... 그리고 응용 프로그램을 다시 실행하십시오. 다음은 디버거를 통해입니다 :

(lldb) po delegate 
Some 
{ 
    Some = { 
    payload_data_0 = 0x0d110b90 -> 0x00009a78 (void *)0x00009b70: OBJC_METACLASS_$__TtC9RicSwift218MainViewController 
    payload_data_1 = 0x0d110b90 -> 0x00009a78 (void *)0x00009b70: OBJC_METACLASS_$__TtC9RicSwift218MainViewController 
    payload_data_2 = 0x00000000 
    instance_type = 0x00000000 
    } 
} 
(lldb) po delegate.hello() 
error: <REPL>:1:1: error: 'ProtocolNameDelegate?' does not have a member named 'hello' 
delegate.hello() 

(lldb) po delegate?.hello() 
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0xb3145b0). 
The process has been returned to the state before expression evaluation. 

질문 :이 없거나 잘못을하고있는 중이 야 무엇? 오히려 (또한 위임 프로토콜이 @objc 것으로 표시되어 있는지 확인해야합니다

delegate?.hello() 

:

답변

0

대표는 선택 사항이기 때문에, 당신이 그것을 풀다해야 빠른 방법은 선택 체인을 사용하는 것입니다 이 경우 @class_protocol보다)

+0

좋아 ... 나는 실종(); 그러나 오타가 원래 문제를 해결하지 못했습니다. 그러나 델리게이트? .hello() 않았다 ...하지만 지금은 런타임 오류 : EXC_BAD_ACCESS (CODE = 2, ...) 대리자에 대한 있어요. (lldb) po delegate.hello() 오류 : : 1 : 1 : 오류 : 'ProtocolNameDelegate?' 'hello'라는 멤버가 없습니다. delegate.hello() –

+0

'EXC_BAD_ACCESS'는 유용하지 않습니다. 그저 무언가가 중단했다고합니다. 당신이 repl에서 그것을 사용할 때 당신은 다시 '?' –

+0

'@ class_protocol'을 생략 해보십시오. –

1

여기에서 문제는 대리인이 선택 사항이라는 것입니다. 그래서이 그렇게 선택 사양 인 랩을 해제하게 당신이

delegate?.hello() 

해야 액세스하고, 비 무기 호

ProtocolNameDelegate 인 경우에 안녕 호출? ProtocolNameDelegate와 구별되는 유형이며, 특히 선택적입니다.

1

나는 동일한 문제가있었습니다. 나는 이것이 Swift (현재 Xcode 6 베타 5에 있음)의 버그라고 들었습니다. 강력한 프로토콜은 잘 작동하지만 약한 프로토콜은 아직 없습니다. 이 문제를 해결하려면 프로토콜을 @objc protocol ProtocolNameDelegate 대신 protocol ProtocolNameDelegate 대신 Objective-C 프로토콜로 선언해야합니다.

관련 문제