Objective c Swift:@objc(…)属性

Objective c Swift:@objc(…)属性,objective-c,swift,cocoa,core-data,nsmanagedobject,Objective C,Swift,Cocoa,Core Data,Nsmanagedobject,在Apple生成的代码(例如,核心数据NSManagedObject子类)中,我看到: @objc(LPFile) public class LPFile: NSManagedObject { ... } 我的问题是:为什么@objc声明是按上述方式进行的,而不是: @objc public class LPFile: NSManagedObject { ... } 或 单独的@objc(标识符)声明有什么特殊之处?我似乎找不到关于它的文档,谷歌搜索只找到了另外两种方法。谢谢 (

在Apple生成的代码(例如,核心数据
NSManagedObject
子类)中,我看到:

@objc(LPFile)
public class LPFile: NSManagedObject {
   ...
}
我的问题是:为什么
@objc
声明是按上述方式进行的,而不是:

@objc public class LPFile: NSManagedObject {
   ...
}

单独的
@objc(标识符)
声明有什么特殊之处?我似乎找不到关于它的文档,谷歌搜索只找到了另外两种方法。谢谢


(注意:我知道类前缀不是惯用的Swift。)

@Alladinian是对的。假设您有一个带有两个类的框架
SharedSwift

@objc公共类Foo:NSObject{}
@objc(Bar)公共类Bar:NSObject{}
您可以在Objective-C代码中导入此框架,并直接使用这两个类:

@import-SharedSwift;
Bar*b=[[Bar alloc]init];
Foo*f=[[Foo alloc]init];
但是因为Objective-C有一个强大的运行时,你可以做很多的魔术。一个例子是函数:

-(id可为null)instanceByName:(NSString*\u Nonnull)name{
c类=NSClassFromString(名称);
返回[[c alloc]init];
}
Foo*Foo=[self instanceByName:@“Foo”];
Bar*Bar=[self-instanceByName:@“Bar”];
NSLog(@“%@%@”,foo,bar);
输出为:

(null) <Bar: 0x6000015c4200>
。。。在一种情况下(
@objc
)返回
SharedSwift.Foo
,在另一种情况下(
@objc(Bar)
)返回
Bar

让我们将另一个swift框架添加到具有相同类的混合中,并尝试从以下两个方面使用
Foo

@import-SharedSwift;
NSLog(@“%@,[Foo className]);//SharedSwift.Foo
@导入另一个swift;
NSLog(@“%@,[Foo className]);//另一个斯威夫特,福
一切正常。在
类中尝试同样的方法:

@import-SharedSwift;
NSLog(@“%@,[Bar className]);//酒吧
@导入另一个swift;
NSLog(@“%@,[Bar className]);//酒吧
Bar
类在这两个框架中都有定义,并且将使用哪一个框架是未定义的。尝试此操作时,请查看控制台中的错误:

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
,…)之间存在差异

Objective-C世界中的所有东西都有一个名称空间。这就是Apple框架中使用这两个字母前缀(
NS
UI
CF
,…)和第三方代码中使用三个字母前缀的原因。一些第三方开发者仍然使用两个字母,但这是另一回事

Swift有更多的名称空间——它们基于模块。当使用pure
@objc
属性时,包含模块名称是安全的。以避免可能出现的歧义

检查类,例如-属性:

表示接收方实体的类的名称


有很多东西利用了Objective-C运行时特性,很多东西仅仅基于名称(字符串),…

@Alladinian是正确的。假设您有一个带有两个类的框架
SharedSwift

@objc公共类Foo:NSObject{}
@objc(Bar)公共类Bar:NSObject{}
您可以在Objective-C代码中导入此框架,并直接使用这两个类:

@import-SharedSwift;
Bar*b=[[Bar alloc]init];
Foo*f=[[Foo alloc]init];
但是因为Objective-C有一个强大的运行时,你可以做很多的魔术。一个例子是函数:

-(id可为null)instanceByName:(NSString*\u Nonnull)name{
c类=NSClassFromString(名称);
返回[[c alloc]init];
}
Foo*Foo=[self instanceByName:@“Foo”];
Bar*Bar=[self-instanceByName:@“Bar”];
NSLog(@“%@%@”,foo,bar);
输出为:

(null) <Bar: 0x6000015c4200>
。。。在一种情况下(
@objc
)返回
SharedSwift.Foo
,在另一种情况下(
@objc(Bar)
)返回
Bar

让我们将另一个swift框架添加到具有相同类的混合中,并尝试从以下两个方面使用
Foo

@import-SharedSwift;
NSLog(@“%@,[Foo className]);//SharedSwift.Foo
@导入另一个swift;
NSLog(@“%@,[Foo className]);//另一个斯威夫特,福
一切正常。在
类中尝试同样的方法:

@import-SharedSwift;
NSLog(@“%@,[Bar className]);//酒吧
@导入另一个swift;
NSLog(@“%@,[Bar className]);//酒吧
Bar
类在这两个框架中都有定义,并且将使用哪一个框架是未定义的。尝试此操作时,请查看控制台中的错误:

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
,…)之间存在差异

Objective-C世界中的所有东西都有一个名称空间。这就是Apple框架中使用这两个字母前缀(
NS
UI
CF
,…)和第三方代码中使用三个字母前缀的原因。一些第三方开发者仍然使用两个字母,但这是另一回事

Swift有更多的名称空间——它们基于模块。当使用pure
@objc
属性时,包含模块名称是安全的。以避免可能出现的歧义

检查类,例如-属性:

表示接收方实体的类的名称


有很多东西利用了Objective-C运行时特性,很多东西只是基于名称(字符串),…

我感觉,
className
在一种情况下返回
(sans@objc(name)),而在另一种情况下只返回
(可能是为了获取
entityName
(?)…它仍然应该使用
@objc
编译。不是吗?@Sweeper它应该,