我之前曾问过一个有关如何使用可选方法创建协议的问题。响应几乎是使用Objective-c。见here

我做到了,并且一切正常,因为我正在使用

var delegate: SessionDelegate?;


也就是说,“ delegate”是可选的SessionDelegate。为了从该委托调用方法,我可以简单地写:

self.delegate?.willOpenSession?(self);


很好但是,然后我为什么要使委托成为可选的呢?所以我改变了它:

var delegate: SessionDelegate;


显然,呼叫也发生了变化:

self.delegate.willOpenSession?(self);


问题是,这最后一行(以及任何其他此类)说:'SessionDelegate'没有名为'willOpenSession'的成员。为什么不起作用?

这是我的代码:

SessionDelegate.h

@class Session;

@protocol SessionDelegate <NSObject>

@optional
- (BOOL)willOpenSession:(Session*)session;
- (void)didOpenSession:(Session*)session;
- (void)didFailOpenningSession:(Session*)session withError:(NSError*)error;

- (BOOL)willCloseSession:(Session*)session destroyingToken:(BOOL)destroyingToken;
- (void)didCloseSession:(Session*)session destroyingToken:(BOOL)destroyingToken;

@end


xxx-Bridging-Header.h

#import <Foundation/Foundation.h>
#import <FacebookSDK/FacebookSDK.h>
#import "SessionDelegate.h"


Session.swift

import Foundation

protocol Session {

    var delegate: SessionDelegate { get set };

    var isOpen: Bool { get };
    var isCached: Bool { get };

    func open();
    func close();
    func destroy();
}


FacebookSession.swift

import Foundation

class FacebookSession : Session {

    var delegate: SessionDelegate;

    var isOpen: Bool {
    get {
        return FBSession.activeSession().isOpen;
    }
    }

    // TODO
    var isCached: Bool {
    get {
        return false;
    }
    }

    init(delegate: SessionDelegate) {
        self.delegate = delegate;
    }

    func open() {

        if self.isOpen {
            return;
        }

        // Trigger the "will" event
        self.delegate.willOpenSession?(self);

        // Handle session state changes
        var completionHandler: FBSessionStateHandler = {

            session, status, error in

            if error {

                // Login failed for some reason, so we notify the delegate.
                // TODO we should turn this NSError message into something more generic (that is, not facebook specific)
                self.delegate.didFailOpenningSession?(self, withError: error);
            }

            else if status.value == FBSessionStateClosedLoginFailed.value {

                // Login failed with no error. I'm not sure this ever happens
                self.delegate.didFailOpenningSession?(self, withError: error);
            }

            else if status.value == FBSessionStateOpen.value || status.value == FBSessionStateOpenTokenExtended.value {

                // Session is now open, we should notify the delegate
                self.delegate.didOpenSession?(self);
            }

            else {

                // There's no error but the session didn't open either. I don't think this ever happens, but if it does, what should we do here?
                abort();
            }
        };

        // Open the session, prompting the user if necessary
        if FBSession.openActiveSessionWithReadPermissions([], allowLoginUI: true, completionHandler: completionHandler) {

            // If we end up here, the session token must exist, se we now have an open session
            self.delegate.d didOpenSession?(self);
        }
    }

    func close() {

    }

    func destroy() {

    }
}


最好的祝福。

编辑:我也尝试了以下

self.delegate.willOpenSession?(self as Session);




self.delegate.willOpenSession(self as Session);


都不行。

编辑:毕竟,如果我使用它是行不通的

var delegate: SessionDelegate?;


编辑:以前的更改也会更改错误消息。现在,我有可选的SessionDelegate(如我在上一次编辑中所说的)和下一行

self.delegate?.willOpenSession?(self)


说:“找不到成员'willOpenSession'”

最佳答案

之所以会出现此错误,是因为您将Session定义为协议,但是SessionDelegate协议中的Objective-C方法定义要求使用Session类或子类。在Swift中,您可以在方法定义中将协议名称与类名称互换使用,但在Objective-C中存在区别:

- (void)willOpenSession:(Session *)session;    // expects instance of Session class or subclass
- (void)willOpenSession:(id<Session>)session;  // expects object conforming to Session protocol


从您发布的代码中,我不知道为什么您将Session声明为协议-它是否为不同的类添加了功能?难道它是FacebookSession(可能还有其他会话)简单地继承的超类吗?将Session更改为类(并添加方法)将解决此问题。否则,您需要更改您的SessionDelegate方法以期望使用id<Session>,但是对我而言,这破坏了编译器。

关于ios - 'SessionDelegate'没有名为'xxx'的成员,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24591921/

10-11 00:27