我开始在Swift项目中遇到问题。我使用Alamofire进行网络连接,将MagicalRecord用作Core Data的包装器。我不知道这是否重要,但无论如何我都会提到它。
应用程序正在从JSON API检索其数据。使用Alamofire's Generic Response Object Serialization我创建了Alamofire.Request
的扩展名,可以在链接页面上看到,并实现了以下协议:
@objc public protocol ResponseObjectSerializable {
init?(response: NSHTTPURLResponse, representation: AnyObject)
}
我创建的课程看起来像这样:
final class Foo: ResponseObjectSerializable {
let bar: String
let baz: String
required init?(response: NSHTTPURLResponse, representation: AnyObject) {
self.bar = representation.valueForKeyPath("bar") as String
self.baz = representation.valueForKeyPath("baz") as String
}
}
要检索JSON数据并将其序列化为Foo
,我所要做的就是以下内容:
Alamofire.request(.GET, "http://foo.com/api").responseObject { (_, _, foo: Foo?, _) in
println(foo.bar)
}
到目前为止,非常好。
当我想添加核心数据功能时问题就出现了。我想使用上面的方法从API检索数据,序列化它,并在某些时候使用Core Data保存它。
所以,我决定将上面的Foo
课程调整为:
@objc(Foo)
final class Foo: NSManagedObject, ResponseObjectSerializable {
@NSManaged var bar: String
@NSManaged var baz: String
required init?(response: NSHTTPURLResponse, representation: AnyObject) {
self.bar = representation.valueForKeyPath("bar") as String
self.baz = representation.valueForKeyPath("baz") as String
}
}
这不起作用,因为NSManagedObject
子类需要指定的初始值设定项,所以我将我的类更改为:
@objc(Foo)
final class Foo: NSManagedObject, ResponseObjectSerializable {
@NSManaged var bar: String
@NSManaged var baz: String
convenience required init?(response: NSHTTPURLResponse, representation: AnyObject) {
let context = NSManagedObjectContext.defaultContext()
let entity = NSEntityDescription.entityForName("Foo", inManagedObjectContext: context)
self.init(entity: entity!, insertIntoManagedObjectContext: context)
self.bar = representation.valueForKeyPath("bar") as String
self.baz = representation.valueForKeyPath("baz") as String
}
}
该项目确实编译,这似乎很有希望,但引发了以下错误:
架构x86_64的未定义符号:
Foo.o中的
" __ TFC7Project3Foo3barSS",引自:TFC7Project3FoocfMS0_FT8responseCSo17NSHTTPURLResponse14representationPSs9AnyObject__GSqS0 ld:找不到架构x86_64的符号
clang:错误:链接器命令失败,退出代码为1(使用-v查看调用)
我不知道它为什么会导致错误,我真的很想摆脱它。那么,有谁知道如何解决这个问题?任何帮助表示赞赏。
我的iOS应用程序中有搜索功能(在模态中)。搜索结果列为Foo
个实例,但我还没有在本地保存任何实例。这种方法只是在UITableView中轻松列出检索到的JSON数据的一种方便方法。
一旦选择了搜索结果(从该列表中),我想使用Core Data将该特定项添加到本地数据库。只有那些保存的项目才会列在应用程序的主视图中。在我看来,使用相同的类似乎很方便。
在创建此问题之前,我尝试谷歌寻找一些解决方案(但可以找到任何可行的答案)并使用此网站上的搜索功能。我发现了一些(有些)相关的问题:
根据this answer,我必须使用Xcode 6.3 beta,我已尝试(6D543q)
,但这也无效。我目前正在使用Xcode 6.2 (6C131e)
btw。
另一个看似相关的问题是answer。所以,我在变量声明中添加了dynamic
:@NSManaged dynamic var bar: String
,但这也不起作用。
我还要注意我是iOS(和Swift)的新手,所以我可能没有使用正确的(或者我应该说推荐的)方法。如果是这种情况,请告诉我,以便我可以采取另一种可能不会导致此错误的方法。
答案 0 :(得分:1)
由于我是Swift的新手,我没有意识到__T
前缀字符串实际上是一个受损的Swift符号。传递给swift-demangle
工具时,会转换为:
__TFC7Project3Foo3barSS ---> Project.Foo.bar.setter : Swift.String
这显然意味着setter方法不存在。根据{{3}}帖子,这是编译器中的一个错误。 @NSManaged
属性完全是动态的,因此托管属性根本不存在此函数,但Swift编译器的某些部分仍会生成使用它的代码。
同一篇文章描述了无论如何都不需要丢失的函数,因此我们可以通过向项目中添加一个简单的C文件来欺骗编译器它的存在:
void _TFC7Project3Foo3barSS() {}
添加文件后,项目构建并运行正常,但它是 hack 。因此,这是一个解决方法,直到它在编译器中实际修复。
据报道它是雷达this。