Swift:@objc(...)属性 [英] Swift: @objc(...) Attribute
问题描述
在Apple生成的代码中(例如,核心数据 NSManagedObject
子类),我看到以下内容:
In Apple-generated code (Core Data NSManagedObject
subclasses, for example) I see this:
@objc(LPFile)
public class LPFile: NSManagedObject {
...
}
我的问题是:为什么 @objc
声明为什么如上所述完成,而不是:
My question is: why is the @objc
declaration done as above, instead of:
@objc public class LPFile: NSManagedObject {
...
}
或
@objcMembers public class LPFile: NSManagedObject {
...
}
单独的 @objc(identifier)
声明有何特别之处?我似乎找不到有关它的文档,而Google搜索只是出现了另外两种方法.谢谢.
What is special about the separate @objc(identifier)
declaration? I can't seem to find documentation about it and googling just turns up the other two approaches. Thanks.
(注意:我知道类前缀不是惯用的Swift.)
(NB: I'm aware class prefixes are not idiomatic Swift.)
推荐答案
@Alladinian是正确的.假设您有一个包含两个类的 SharedSwift
框架:
@Alladinian is right. Suppose you have a framework SharedSwift
with two classes:
@objc public class Foo: NSObject {}
@objc(Bar) public class Bar: NSObject {}
您可以在Objective-C代码中导入此框架,并直接使用这两个类:
You can import this framework in the Objective-C code and use these two classes directly:
@import SharedSwift;
Bar *b = [[Bar alloc] init];
Foo *f = [[Foo alloc] init];
但是因为Objective-C具有强大的运行时,所以您可以做很多 magic .一个示例是 NSClassFromString
功能:
But because Objective-C has a powerful runtime, you can do a lot of magic. One example is the NSClassFromString
function:
- (id _Nullable)instanceByName:(NSString * _Nonnull)name {
Class c = NSClassFromString(name);
return [[c alloc] init];
}
Foo *foo = [self instanceByName:@"Foo"];
Bar *bar = [self instanceByName:@"Bar"];
NSLog(@"%@ %@", foo, bar);
输出为:
(null) <Bar: 0x6000015c4200>
出什么问题了? className
...
What's the problem? className
...
NSLog(@"%@ %@", [Foo className], [Bar className]);
...在一种情况下返回 SharedSwift.Foo
( @objc
),在另一种情况下返回 Bar
( @objc(条)
).
... returns SharedSwift.Foo
in one case (@objc
) and Bar
in another one (@objc(Bar)
).
SharedSwift.Foo Bar
让我们将 AnotherSwift
框架添加到具有相同类的组合中,并尝试同时使用两者中的 Foo
:
Let's add AnotherSwift
framework to the mix with same classes and try to use Foo
from both:
@import SharedSwift;
NSLog(@"%@", [Foo className]); // SharedSwift.Foo
@import AnotherSwift;
NSLog(@"%@", [Foo className]); // AnotherSwift.Foo
按预期工作.使用 Bar
类尝试相同的操作:
Works as expected. Try the same thing with the Bar
class:
@import SharedSwift;
NSLog(@"%@", [Bar className]); // Bar
@import AnotherSwift;
NSLog(@"%@", [Bar className]); // Bar
在两个框架中都定义了
Bar
类,并且未定义使用哪个类.尝试执行此操作时,请在控制台中看到错误:
Bar
class is defined in both frameworks and which one will be used is undefined. See the error in the console when you try this:
Class Bar is implemented in both
.../Debug/SharedSwift.framework/Versions/A/SharedSwift (0x102b931c0) and
.../Debug/AnotherSwift.framework/Versions/A/AnotherSwift (0x102b841c0).
One of the two will be used. Which one is undefined.
这是什么原因?
如您所见,Objective-C代码( @import SharedSwift
和直接使用 Foo
)和Objective-C运行时名称( NSClassFromString
,...).
As you can see, there's a difference between Objective-C code (@import SharedSwift
& direct usage of Foo
) & Objective-C runtime name (NSClassFromString
, ...).
Objective-C世界中的所有内容都有一个名称空间.这就是Apple框架中这两个字母前缀( NS
, UI
, CF
,...)和三个字母前缀的原因.第三方代码.一些第三方开发人员仍然使用两个字母,但这是另一回事.
There's one namespace for everything in the Objective-C world. This is the reason for these two letters prefixes in the Apple frameworks (NS
, UI
, CF
, ...) and three letters prefixes in the 3rd party code. Some 3rd party developers still do use two letters, but that's another story.
Swift具有更多的命名空间-它们基于模块.使用纯 @objc
属性时,最好包含模块名称.为了避免可能的歧义.
Swift has more namespaces - they're based on modules. It's a safe bet to include module name when the pure @objc
attribute is used. To avoid possible ambiguity.
检查 NSEntityDescription
类例如- managedObjectClassName
属性:
Check the NSEntityDescription
class for example - managedObjectClassName
property:
代表接收者实体的类的名称.
The name of the class that represents the receiver’s entity.
有很多东西可以利用Objective-C运行时功能,很多东西只是基于名称(字符串),...
There's a lot of stuff around which leverages Objective-C runtime features, lot of stuff is based on just names (strings), ...
这篇关于Swift:@objc(...)属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!