将目标C robbiehanson / XMPPFramework导入swift项目(设置构建设置,桥接标题等)。我能够在导入的类中调用常规方法并直接设置属性。
但是,某些设置属性的实例方法会导致立即出现错误,就好像它们在我调用它们的实例中不存在一样。例如:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
甚至是实际进行设置的setMyJID_setByClient:newMyJID
方法。
在我看过的两个单独的Objective c示例项目中,从其他类调用了setMyJID方法。但是,虽然我能够在类上调用其他实例方法,但我无法调用此方法。由于我对目标c不是很熟悉,我可能因为它没有在头文件中声明,导致一些特定的快速问题,但尝试为它添加声明并没有帮助。
我能够直接设置相关属性,但这不仅是不可取的,我也想了解为什么我无法调用某些方法。
我试图像这样
在XMPPStream类的实例上进行调用 //This shows immediate error: XMPPStream does not have a member named 'setMyJID'
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
// This works perfectly
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
任何帮助都将不胜感激。
答案 0 :(得分:1)
在XMPPStream
课程中,myJID
声明如下:
@property (readwrite, copy) XMPPJID *myJID;
在Objective-C中,这意味着XMPPStream
类实际上有两个符合以下签名的方法:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
因此,从Objective-C代码中,您可以像任何其他方法一样调用它们。但是,如您所知,您还可以选择使用称为“点符号”的语言来使用语法糖:
// getter with dot notation
XMPPJID *jid = stream.myJID;
// setter with dot notation
stream.myJID = jid;
但是,在Objective-C中,这些点符号表达式直接翻译到对getter和setter的调用中。他们只是在那里看起来不错。
Swift的情况有所不同。当你有一个属性,像这样:
var myJID: XMPPJID
这个不意味着存在单独的getter和setter方法,就像你可能想象的那样:
func myJID() -> XMPPJID {}
func setMyJID(jid: XMPPJID) {}
在Swift中,您必须使用点语法访问属性。
知道这一点,你的问题就变得很明显了。当你尝试:
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
Swift试图运行setMyJID
的实例方法stream
,并且正确地发现它不存在!这当然是:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
完美无缺,因为你正在按照Swift的要求设置属性。
作为一种教育,除了从Swift访问Objective-C属性之外,您有时可能会看到这样的情况:必须使用getter和setter方法 - 点符号不会甚至工作!这似乎完全违反直觉,但有充分的理由说明为什么会这样。我能想到的一个例子就是用于视图布局的详细命名的UIView
属性translatesAutoresizingMaskIntoConstraints
。如果你试图在Swift中使用它,就像这样:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
你会收到编译错误!具体来说,
无法在'self'中指定'translatesAutoresizingMaskIntoConstraints'
为什么呢?答案在于UIView
标题:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
事实证明,这个“属性”,就像Cocoa框架中的许多其他属性一样,实际上只是一对看起来像属性访问器的方法。由于Objective-C如何将点符号转换为方法调用,您以前从未注意到。但现在,Swift更严格 - 要获得并设置这个“属性”,你必须调用适当的方法。