使用 Parse 注册子类时出现异常
Exception while registering subclass with Parse
我有一个名为 Attendee
的 class,它继承自 PFObject
。在我的 applicationDidFinishLaunching()
方法中,我像这样注册子 class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Attendee.initialize()
Parse.enableLocalDatastore()
Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)
getData()
return true
}
func getData() {
//create the query
var attendeeQuery = Attendee.query()
attendeeQuery?.fromLocalDatastore()
.fromPinWithName(CacheKeys.AttendeesKey)
.whereKey("conference", equalTo: ObjectManager.currentConf)
//register a background task
var bgTask = UIBackgroundTaskInvalid
bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in
UIApplication.sharedApplication().endBackgroundTask(bgTask)
bgTask = UIBackgroundTaskInvalid
println("Attendees Loader Expiration Handler called")
})
//run the query
attendeeQuery?.findObjectsInBackgroundWithBlock({ (cachedAttendees: [AnyObject]?, error:NSError?) -> Void in
if error != nil {
println(error)
return
}
...
UIApplication.sharedApplication().endBackgroundTask(bgTask)
})
})
}
但是,当我 运行 代码时,我在 var attendeeQuery = Attendee.query()
行遇到异常。异常说我在使用它之前需要注册 Attendee
subclass 。我不明白为什么这么说,因为我事先就注册了。下面是 Attendee
class 的定义。
class Attendee: PFObject, PFSubclassing {
var name:String
{
return self["name"] as! String
}
...
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return Classes.Attendee
}
}
异常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The class MedConf.Attendee must be registered with registerSubclass before using Parse.'
*** First throw call stack:
(0x1835002d8 0x194d240e4 0x183500218 0x1001e21d0 0x1001e1fac 0x100135d88 0x100138af0 0x1000e43e0 0x1000e4580 0x187fb3190 0x1881ca854 0x1881cd208 0x1881cb778 0x18bd093c8 0x1834b827c 0x1834b7384 0x1834b59a8 0x1833e12d4 0x187fac43c 0x187fa6fac 0x1000e7b48 0x1953a2a08)
如果出现 must be registered with registerSubclass
的错误呢?
因此您需要调用 registerSubclass
方法而不是 initialize
下面是代码:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Attendee.registerSubclass()
Parse.enableLocalDatastore()
Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)
getData()
return true
}
我从 1.6.3 升级到 Parse 的 iOS SDK 1.7.5 时遇到了同样的问题。问题出在我的初始化函数中,它看起来和你的一样。
在函数中使用 dispatch_once_t 作为局部变量并不能确保子类只被注册一次;我注意到在初始化函数中的 registerSubclass() 调用上放置了一个断点,它被调用了很多次。子类的不断重新注册显然导致新版本的 Parse SDK 出现问题。
将初始化函数改成这样解决了问题:
private static var onceToken : dispatch_once_t = 0
override class func initialize() {
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
我有一个名为 Attendee
的 class,它继承自 PFObject
。在我的 applicationDidFinishLaunching()
方法中,我像这样注册子 class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Attendee.initialize()
Parse.enableLocalDatastore()
Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)
getData()
return true
}
func getData() {
//create the query
var attendeeQuery = Attendee.query()
attendeeQuery?.fromLocalDatastore()
.fromPinWithName(CacheKeys.AttendeesKey)
.whereKey("conference", equalTo: ObjectManager.currentConf)
//register a background task
var bgTask = UIBackgroundTaskInvalid
bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in
UIApplication.sharedApplication().endBackgroundTask(bgTask)
bgTask = UIBackgroundTaskInvalid
println("Attendees Loader Expiration Handler called")
})
//run the query
attendeeQuery?.findObjectsInBackgroundWithBlock({ (cachedAttendees: [AnyObject]?, error:NSError?) -> Void in
if error != nil {
println(error)
return
}
...
UIApplication.sharedApplication().endBackgroundTask(bgTask)
})
})
}
但是,当我 运行 代码时,我在 var attendeeQuery = Attendee.query()
行遇到异常。异常说我在使用它之前需要注册 Attendee
subclass 。我不明白为什么这么说,因为我事先就注册了。下面是 Attendee
class 的定义。
class Attendee: PFObject, PFSubclassing {
var name:String
{
return self["name"] as! String
}
...
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return Classes.Attendee
}
}
异常:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The class MedConf.Attendee must be registered with registerSubclass before using Parse.'
*** First throw call stack:
(0x1835002d8 0x194d240e4 0x183500218 0x1001e21d0 0x1001e1fac 0x100135d88 0x100138af0 0x1000e43e0 0x1000e4580 0x187fb3190 0x1881ca854 0x1881cd208 0x1881cb778 0x18bd093c8 0x1834b827c 0x1834b7384 0x1834b59a8 0x1833e12d4 0x187fac43c 0x187fa6fac 0x1000e7b48 0x1953a2a08)
如果出现 must be registered with registerSubclass
因此您需要调用 registerSubclass
方法而不是 initialize
下面是代码:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Attendee.registerSubclass()
Parse.enableLocalDatastore()
Parse.setApplicationId(ObjectManager.appID, clientKey: ObjectManager.clientKey)
getData()
return true
}
我从 1.6.3 升级到 Parse 的 iOS SDK 1.7.5 时遇到了同样的问题。问题出在我的初始化函数中,它看起来和你的一样。
在函数中使用 dispatch_once_t 作为局部变量并不能确保子类只被注册一次;我注意到在初始化函数中的 registerSubclass() 调用上放置了一个断点,它被调用了很多次。子类的不断重新注册显然导致新版本的 Parse SDK 出现问题。
将初始化函数改成这样解决了问题:
private static var onceToken : dispatch_once_t = 0
override class func initialize() {
dispatch_once(&onceToken) {
self.registerSubclass()
}
}