'does not have member' 从 Swift 调用 objective C setter 方法时
'does not have member' when calling objective C setter method from Swift
将 objective C robbiehanson/XMPPFramework 导入 swift 项目后(设置构建设置、桥接头等)。我可以在导入的 classes 中调用普通方法并直接设置属性。
但是,某些设置属性的实例方法会立即导致错误,就好像它们不存在于我调用它们的实例中一样。例如:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
甚至 setMyJID_setByClient:newMyJID
实际进行设置的方法。
在我看过的两个单独的 objective c 示例项目中,其他 classes 正在调用 setMyJID 方法。但是,虽然我可以调用 class 上的其他实例方法,但我不能调用这个方法。由于我对 objective c 不是很熟悉,我认为这可能是因为它没有在头文件中声明,导致一些 swift 特定问题,但尝试为其添加声明并没有帮助.
我可以直接设置相关的属性,但这不仅不可取,我也想明白为什么我不能调用某些方法。
我正在尝试像这样对 XMPPStream class 的实例进行调用
//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))
如有任何帮助,我们将不胜感激。
在XMPPStream
class中,myJID
声明如下:
@property (readwrite, copy) XMPPJID *myJID;
在Objective-C中,这意味着XMPPStream
class上实际上有两个方法符合如下签名:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
因此,从 Objective-C 代码中,您可以像调用任何其他方法一样调用它们。但是,如您所知,您还可以选择使用称为 "dot notation":
的语言中的语法糖
// 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尝试运行stream
的实例方法setMyJID
,结果发现,没错,不存在!这当然是:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
完美运行,因为您设置了 属性 作为 Swift 的要求。
除了教育之外,您有时可能会看到这样的情况,当从 Swift 访问 Objective-C 属性时,您不仅可以,而且 必须 使用getter 和 setter 方法 - 点符号甚至不起作用!这似乎完全违反直觉,但这是有充分理由的。我能想到的一个例子是 verbosely-named UIView
属性 translatesAutoresizingMaskIntoConstraints
,用于视图布局。如果你尝试在 Swift 中使用它,就像这样:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
你会得到一个编译错误!具体来说,
Cannot assign to 'translatesAutoresizingMaskIntoConstraints' in 'self'
为什么?答案就在UIView
headers:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
事实证明,这个 "property," 与 Cocoa 框架中的许多其他方法一样,实际上只是一对 看起来 类似于 [=92] 的方法=] 访问器。由于 Objective-C 将点符号转换为方法调用的方式,您以前从未注意到。不过,现在 Swift 更严格了——要获取和设置这个 "property,",您必须调用适当的方法。
将 objective C robbiehanson/XMPPFramework 导入 swift 项目后(设置构建设置、桥接头等)。我可以在导入的 classes 中调用普通方法并直接设置属性。
但是,某些设置属性的实例方法会立即导致错误,就好像它们不存在于我调用它们的实例中一样。例如:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
甚至 setMyJID_setByClient:newMyJID
实际进行设置的方法。
在我看过的两个单独的 objective c 示例项目中,其他 classes 正在调用 setMyJID 方法。但是,虽然我可以调用 class 上的其他实例方法,但我不能调用这个方法。由于我对 objective c 不是很熟悉,我认为这可能是因为它没有在头文件中声明,导致一些 swift 特定问题,但尝试为其添加声明并没有帮助.
我可以直接设置相关的属性,但这不仅不可取,我也想明白为什么我不能调用某些方法。
我正在尝试像这样对 XMPPStream class 的实例进行调用
//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))
如有任何帮助,我们将不胜感激。
在XMPPStream
class中,myJID
声明如下:
@property (readwrite, copy) XMPPJID *myJID;
在Objective-C中,这意味着XMPPStream
class上实际上有两个方法符合如下签名:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
因此,从 Objective-C 代码中,您可以像调用任何其他方法一样调用它们。但是,如您所知,您还可以选择使用称为 "dot notation":
的语言中的语法糖// 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尝试运行stream
的实例方法setMyJID
,结果发现,没错,不存在!这当然是:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
完美运行,因为您设置了 属性 作为 Swift 的要求。
除了教育之外,您有时可能会看到这样的情况,当从 Swift 访问 Objective-C 属性时,您不仅可以,而且 必须 使用getter 和 setter 方法 - 点符号甚至不起作用!这似乎完全违反直觉,但这是有充分理由的。我能想到的一个例子是 verbosely-named UIView
属性 translatesAutoresizingMaskIntoConstraints
,用于视图布局。如果你尝试在 Swift 中使用它,就像这样:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
你会得到一个编译错误!具体来说,
Cannot assign to 'translatesAutoresizingMaskIntoConstraints' in 'self'
为什么?答案就在UIView
headers:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
事实证明,这个 "property," 与 Cocoa 框架中的许多其他方法一样,实际上只是一对 看起来 类似于 [=92] 的方法=] 访问器。由于 Objective-C 将点符号转换为方法调用的方式,您以前从未注意到。不过,现在 Swift 更严格了——要获取和设置这个 "property,",您必须调用适当的方法。