Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios ';SessionLegate';没有名为'的成员;xxx和x27;_Ios_Objective C_Ios7_Swift_Xcode6 - Fatal编程技术网

Ios ';SessionLegate';没有名为'的成员;xxx和x27;

Ios ';SessionLegate';没有名为'的成员;xxx和x27;,ios,objective-c,ios7,swift,xcode6,Ios,Objective C,Ios7,Swift,Xcode6,我之前问了一个关于如何创建带有可选方法的协议的问题。答案是,基本上,使用Objective-c。看到了 我做到了,一切都很好,因为我在使用 var delegate: SessionDelegate?; 也就是说,“委托”是可选的SessionLegate。为了从该委托调用方法,我可以简单地编写: self.delegate?.willOpenSession?(self); 这很好。但是我想,为什么要让委托成为可选的呢?所以我改变了它: var delegate: SessionDelega

我之前问了一个关于如何创建带有可选方法的协议的问题。答案是,基本上,使用Objective-c。看到了

我做到了,一切都很好,因为我在使用

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

self.delegate?.willOpenSession?(self);
这很好。但是我想,为什么要让委托成为可选的呢?所以我改变了它:

var delegate: SessionDelegate;
显然,通话也会发生变化:

self.delegate.willOpenSession?(self);
问题是,最后一行(以及任何其他类型)说:“SessionDelegate”没有名为“willOpenSession”的成员。为什么这样不行

这是我的密码:

SessionedLegate.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
斯威夫特

import Foundation

protocol Session {

    var delegate: SessionDelegate { get set };

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

    func open();
    func close();
    func destroy();
}
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);

两者都不起作用

编辑:毕竟,如果我使用

var delegate: SessionDelegate?;
编辑:前面的更改也会更改错误消息。现在我有了可选的SessionDelegate(正如我在上一次编辑中所说的)和下面一行

self.delegate?.willOpenSession?(self)

说明:“找不到成员‘willOpenSession’”

您遇到此错误,因为您将
Session
定义为协议,但
SessionLegate
协议中的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
-(void)willOpenSession:(Session*)Session;//需要会话类或子类的实例
-(void)willOpenSession:(id)session;//期望对象符合会话协议

从您发布的代码中,我无法解释您为什么将
会话
声明为协议——它是否为不同的类添加了功能?它会不会是一个超类,而FacebookSession(可能还有其他会话)只是继承自它?将
Session
更改为类(并将方法存根)可以解决此问题。否则,您需要更改您的
SessionDelegate
方法以获得
id
,但对我来说,这破坏了编译器。

这是有意义的。如果可能的话,我希望避免对方法进行存根,因此我会在这件事上坚持一段时间,这意味着
会话
仍然是一个协议。显然,如果这不起作用,我会这么做。现在我得到“SessionDelegate.h:16:找不到‘Session’的协议声明”。我是否必须更改
@课堂会话以任何方式?我在所有地方添加了
id
声明,正如您所建议的那样,我将其更改为
@协议会话并且它工作!非常感谢!!=)我想我说得太快了。这也破坏了我的编译器,我将使用存根。刚刚意识到你可以有一个
Session
类和一个单独的
SessionProtocol
协议用于方法。在Swift中,子类可以继承这两个类,并且它应该与ObjC配合使用。
self.delegate?.willOpenSession?(self)
- (void)willOpenSession:(Session *)session;    // expects instance of Session class or subclass
- (void)willOpenSession:(id<Session>)session;  // expects object conforming to Session protocol