如何更改 Swift 类的命名空间?

Posted

技术标签:

【中文标题】如何更改 Swift 类的命名空间?【英文标题】:How to change the namespace of a Swift class? 【发布时间】:2015-01-15 23:33:19 【问题描述】:

当您在 Swift 中实现类 MyGreatClass 时,它的完全限定名称将由 <MyPackageName>.MyGreatClass。这与 Objective-C 不同,后者的同一类的完全限定名称是 MyGreatClass

不幸的是,这给我带来了一个问题。当我使用 NSUnarchiver 并且存档是用 Objective-C 对象编写时,我无法使用 Swift-classes 解压缩它(详细说明见下文)。

这意味着我需要找到一种方法来重命名我的 Swift 类的命名空间。我该怎么做?

任何帮助都会很棒!

背景:为什么 NSUNarchiver 看不到/加载我的 swift 类?

我已经实现了一个小程序来读取一个文件,该文件被归档为NSArchive。 这些是我的文件:

main.swift:

import Foundation

// parse command line - total path to *.trace file (from Apple's Instruments app)
var traceFilePath = Process.arguments[1]

var traceFile = NSURL(fileURLWithPath: traceFilePath)
var error:NSError?

// check if the file exists
if (traceFile?.checkResourceIsReachableAndReturnError(&error) == false)
    // file does not exist or cannot be accessed
    println("\(error)")
    exit(1)


var rawData = NSData(contentsOfURL: traceFile!)
var data = NSUnarchiver(forReadingWithData: rawData!)
var decodedObject: AnyObject? = data?.decodeObject()

XRObjectAllocRun.swift

import Foundation

class XRObjectAllocRun: NSObject 
    // class to be implemented   

当我现在在 Instruments 文件上运行我的应用程序时,我收到以下错误:Terminating app due to uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun': class not loaded'

这真的很奇怪,因为当我在带有 桥接头 文件的 Objective-C 文件中添加完全相同的类时,我没有任何问题。

trace file reader-Bridging-Header.h: 为空。

XRObjectAllocRun.h:

#import <Foundation/Foundation.h>
@interface XRObjectAllocRun : NSObject
@end

XRObjectAllocRun.m:

#import "XRObjectAllocRun.h"
@implementation XRObjectAllocRun
@end

我错过了什么?为什么找到我的Objective-C 类,而我的Swift 类却没有? Swift 没有问题,例如 main.swift 中的 var x = XRObjectAllocRun(),但是当我完全呆在 Swift 中时,NSUnarchiver 仍然抱怨缺少 XRObjectAllocRun 类。 NSUnarchiver 是不是找错地方了——它是否出于某种原因只接受 Objective-C 类?

如果你想知道我想做什么,请查看*** question。

更新

这是苹果写的:

Swift 类的命名空间基于它们编译所在的模块,即使是在 Objective-C 代码中使用时也是如此。与 Objective-C 不同,所有类都是全局命名空间的一部分

更多:

例如,当您创建基于文档的 Mac 应用程序时,您需要在应用程序的 Info.plist 文件中提供 NSDocument 子类的名称。在 Swift 中,您必须使用文档子类的全名,包括从您的应用或框架名称派生的模块名称。

哎呀,现在想弄清楚这个烂摊子......

【问题讨论】:

问题可能是您的代码中没有对 XRObjectAllocRun 的实际引用吗?我认为它不会加载,除非其他一些代码谈论它。 这是我最初的想法。但是我在var rawData = NSData(contentsOfURL: traceFile!) 之前添加了var x = XRObjectAllocRun(),但我仍然遇到同样的错误。当我在崩溃前检查x 时,我看到(trace_file_reader.XRObjectAllocRun) $R0 = 0x0000000102000040 (ObjectiveC.NSObject = ) 这是Objective-C 对象在调试控制台上打印的内容:(XRObjectAllocRun) $R0 = 0x00000001020004b0 ObjectiveC.NSObject = 。注意区别:(swift) trace_file_reader.XRObjectAllocRun vs (ObjC) XRObjectAllocRun。我可以以某种方式快速删除命名空间吗? 是的,您可以使用@objc(XRObjectAllocRun) 声明它。我想这可能就是这里的答案。我会给出答案! 干得好,在您完成所有侦探工作之后,您真的修改了这个问题并很好地集中注意力。否则我想不出答案! 【参考方案1】:

当你声明你的类时试试这个:

@objc(XRObjectAllocRun) class XRObjectAllocRun: NSObject 
    // class to be implemented   

这将使该类与归档类具有相同的名称,即 XRObjectAllocRun,而不是命名空间的 Swift 名称 trace_file_reader.XRObjectAllocRun

当您从 Objective-C 翻译到 Swift 并且您有一个现有的档案要处理时,这总是一个问题。请参阅 Apple 的文档:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html

请注意“在 Objective-C 中公开 Swift 接口”下的讨论。

【讨论】:

我在我的新 Swift 教程中谈到了 @objc(...) 有用的其他一些地方:apeth.com/swiftBook/…

以上是关于如何更改 Swift 类的命名空间?的主要内容,如果未能解决你的问题,请参考以下文章

在实体框架中更改命名空间

C#中如何获得指定命名空间中所有自定义类的信息

c#如何获取某一命名空间下的所有的类的信息(方法以及参数)

C# - 在共享命名空间中跨文件使用命名空间

Swift 反射机制,命名空间

C# |如何更改 XML 文档中的命名空间?