Swift:@objc(...)属性 [英] Swift: @objc(...) Attribute

查看:83
本文介绍了Swift:@objc(...)属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆