在访问 PFObject 成员时解析“发送到实例的无法识别的选择器”

Posted

技术标签:

【中文标题】在访问 PFObject 成员时解析“发送到实例的无法识别的选择器”【英文标题】:Parse "unrecognized selector sent to instance" while accessing PFObject members 【发布时间】:2015-09-09 02:37:55 【问题描述】:

我在使用点符号访问成员字段时遇到了一个奇怪的问题。示例:

设置模型

class SettingsModel: PFObject, PFSubclassing 

    override class func initialize() 
        struct Static 
            static var onceToken : dispatch_once_t = 0;
        
        dispatch_once(&Static.onceToken) 
            self.registerSubclass()
        
    

    static func parseClassName() -> String 
        return "Settings"
    

    @NSManaged var name:String
    @NSManaged var code:String
    @NSManaged var friend:FriendsModel


朋友模型

class FriendsModel: PFObject, PFSubclassing 

    override class func initialize() 
        struct Static 
            static var onceToken : dispatch_once_t = 0;
        
        dispatch_once(&Static.onceToken) 
            self.registerSubclass()
        
    

    static func parseClassName() -> String 
        return "Friends"
    

    @NSManaged var user:PFUser
    @NSManaged var settings:SettingsModel

当我尝试使用 mySettings.friend.settings.name 访问朋友姓名时,我在“设置”上遇到无法识别的选择器。

但有趣的是,当我使用 (mySettings.friend["settings"] as SettingsModel).name 时,它可以工作。我故意省略了所有条件展开等 - 我有正确类型的有效 PFObject 和所有数据......

我确定这是一件微不足道的事情,但无法弄清楚...任何帮助将不胜感激。使用解析 1.8.2。

【问题讨论】:

你能给我们更多的背景信息吗?喜欢整个类的声明? 你的意思是模型类?它们只是标准的 Parse 子类模板,但我还是添加了它们。干杯 @Tom 你找出问题所在了吗?我遇到了同样的问题。 不幸的是,它仍然不适合我。我正在使用原始问题中提到的解决方法 为什么使用 CoreData 的@NSManaged?因此,getter/setter 的解决方法和点符号的问题似乎是正确的(请参阅***.com/a/24015789/1801544 的引用) 【参考方案1】:

看起来FriendsModel 没有成功注册为 Parse 子类,尽管您实现了 PFSubclassing。当您通过mySettings.friend.settings.name 访问它时,可能还没有调用FriendsModelinitialize()

要解决此问题,您可以通过在调用 Parse.setApplicationId(..) 的位置之前调用 FriendsModel.registerSubclass() 来在 Parse 中注册您的 FriendsModel 子类。

这就是我自己解决这些问题的方法,我希望它对你的情况也有帮助。

【讨论】:

我怀疑这可能是最初的问题,所以我添加了 SettingsModel.initialize() 和 FriendsModel.initialize() 作为 AppDelegate 中的第一件事。但可惜没有帮助。 registerSubclass() 方法对我有用并解决了问题:) 我遇到了同样的问题,肯定会调用 [MyClass registerSubclass],甚至尝试重新安排它以确保首先注册嵌套的类,以防出现问题。虽然,密钥访问器帮助我暂时解决了这个问题。【参考方案2】:

哇...我想我找到了您问题背后的原因,但这将是“这到底是怎么回事”类型的解决方案之一。我遇到了这个线程,因为我收到了相同的错误消息,而且我几乎处于类似的环境中(解析、子类化、快速)。我的应用程序崩溃的那一行是:

let setOpts = self.thing?.settingOptions

其中变量“thing”表示 PFObject 以及“settingOptions”。所以我认为这可能也是错误注册子类的问题,尽管我认为在最近的 Parse 版本中不再需要了(我使用的是 v1.15.1)。无论如何,您提供的解决方法起初有所帮助,但让我的应用在下一行崩溃:

if (self.thing?.setting != nil) ...

然后它让我开始思考......等一下......“事物”的其他几个属性通过点符号访问,它们之间没有崩溃,为什么又在这里?!当我再次查看您的帖子时,它正中我的脸。我希望现在每个人都看到它,因为如果我告诉你,你可能不相信我......但无论如何我都会:

我们使用的属性都是以setting开头的。

似乎就是这样。我不知道他们是否应该以“set”或“setti”开头,但绝对不能以“setting”开头。一旦我将名称更改为完全不同的名称,它就起作用了。也许类名也是相关的,但我的以前缀开头,所以“设置”只是名称的一部分。希望这会有所帮助;)

【讨论】:

哇。我不敢相信我能找到这个答案是多么幸运。我可以很容易地看到自己在接下来的 5 个小时内解决了这个问题。谢谢大佬。 omfg.我可以确认这一点。我有一个 PFObject 子类,它有一个名为“sets”的属性。 (即一组重复,用于练习)。莫名的崩溃。绝望地用谷歌搜索,偶然发现了这个答案。更改为“repSets”,并且有效。 ://【参考方案3】:

不知道为什么会发生这种情况,但我正在使用一种在我看来稍微干净的解决方法,因为解决方法只在一个地方。即使用 swift 的 setter 和 getter 功能。

class SettingsModel: PFObject, PFSubclassing 

override class func initialize() 
    struct Static 
        static var onceToken : dispatch_once_t = 0;
    
    dispatch_once(&Static.onceToken) 
        self.registerSubclass()
    


static func parseClassName() -> String 
    return "Settings"


@NSManaged var name:String
@NSManaged var code:String
var friend:FriendsModel
    
        get
        
             return self["friend"] as! FriendsModel 
        
        set
        
             self["friend"] = newValue
        
    


【讨论】:

以上是关于在访问 PFObject 成员时解析“发送到实例的无法识别的选择器”的主要内容,如果未能解决你的问题,请参考以下文章

PFObject 在 Xcode 6.0.1、Yosemite GM3 中没有名为“saveInBackground”的成员

最终使用 PFFile(解析本地数据存储)保存在 PFObject 上?

如何在 iOS 中保存 PFObject 列表?

如何对 PFObject 进行分组?解析/斯威夫特

解析 Cloud Code 关系查询语法

Swift - PFObject 从保存回调而不是布尔返回自身