Исключение при регистрации подкласса с помощью Parse

У меня есть класс Attendee, который наследуется от PFObject. В моем методе applicationDidFinishLaunching() я регистрирую подкласс следующим образом:

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, прежде чем использовать его. Я не понимаю, почему он говорит это, поскольку я регистрирую это прямо заранее. Ниже приведено определение класса Attendee.

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)

person Satre    schedule 02.07.2015    source источник
comment
Classes.Attendee возвращает строку "Attendee"?   -  person kRiZ    schedule 02.07.2015
comment
Да, он возвращает Attendee struct Classes { static let Attendee = "Attendee" }   -  person Satre    schedule 02.07.2015
comment
У меня возникла та же проблема после недавнего обновления библиотеки синтаксического анализа 1.6.3 до 1.7.5. Удалось ли вам определить, в чем причина была в вашем приложении?   -  person Greg    schedule 04.08.2015


Ответы (2)


У меня была такая же проблема, когда я обновился до Parse iOS SDK 1.7.5 с 1.6.3. Проблема была в моей функции инициализации, которая выглядела так же, как ваша.

Использование dispatch_once_t в качестве локальной переменной в функции не гарантирует, что подкласс будет зарегистрирован ровно один раз; Поставив точку останова на вызове registerSubclass() в функции инициализации, я заметил, что она вызывалась много раз. Постоянная перерегистрация подкласса явно вызывала проблемы для новой версии Parse SDK.

Изменение функции инициализации, чтобы она выглядела так, устранила проблему:

private static var onceToken : dispatch_once_t = 0

override class func initialize() {
    dispatch_once(&onceToken) {
        self.registerSubclass()
    }
}
person Greg    schedule 04.08.2015

Как насчет ошибки, которая говорит 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
}
person siegy22    schedule 07.07.2015
comment
Да, но сам метод initialize() вызывает registerSubclass() - person Satre; 07.07.2015