如何更改 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 类的命名空间?的主要内容,如果未能解决你的问题,请参考以下文章