在 Swift 中子类化 PFObject
Posted
技术标签:
【中文标题】在 Swift 中子类化 PFObject【英文标题】:Subclassing PFObject in Swift 【发布时间】:2014-07-05 00:38:00 【问题描述】:用于在 PFObject 子类上添加属性和方法的 Parse 文档在其示例代码中方便地跳过了 Swift 语法,仅列出了 Objective-C 语法:
https://parse.com/docs/ios_guide#subclasses-properties/iOS
// Armor.h
@interface Armor : PFObject<PFSubclassing>
+ (NSString *)parseClassName;
@property (retain) NSString *displayName;
@end
// Armor.m
@dynamic displayName;
有没有人想出解决 Swift 缺少动态合成器的方法,以便使用 PFSubclassing 实现属性和方法?我希望能够做类似的事情:
class Armor : PFObject, PFSubclassing
class func parseClassName() -> String!
return "Armor"
var armor = Armor()
armor.displayName = "Iron Clad"
【问题讨论】:
“方便跳过”是指“尚未添加,因为您只能在 beta IDE 中使用该语言”? 所有你需要做的就是在你的类中添加var displayName = "default"
,你应该完成......(另外,没有理由让 parseClassName 返回一个String!
- String
是完全足够的。
【参考方案1】:
我遇到了同样的问题。必须将 @NSManaged 添加到我想要保存的属性中:
class Armor : PFObject, PFSubclassing
@NSManaged var displayName: String
class func parseClassName() -> String!
return "Armor"
var armor = Armor.object()
armor.displayName = "Iron Clad"
希望在下一次更新中解决这个问题。
【讨论】:
似乎是一个很好的临时解决方案。 Swift 文档说:Like the @dynamic attribute in Objective-C, the @NSManaged attribute informs the Swift compiler that the storage and implementation of a property will be provided at runtime. However, unlike @dynamic, the @NSManaged attribute is available only for Core Data support.
希望 Parse 尽快发布官方解决方案。【参考方案2】:
解决方案是使用计算属性而不是存储属性:
class Armor : PFObject, PFSubclassing
var displayName: String?
get
return self["displayName"] as? String
set
self["displayName"] = newValue
class func parseClassName() -> String
return "Armor"
【讨论】:
OP 需要接受这个作为答案,因为它也对我有用。多亏了这个答案,我不必浪费几个小时来解决这个问题。 Parse 还需要更新他们的文档,而不是依赖 SO 来记录他们快速做事的方法。 你仍然可以使用下标语法:)self["displayName"] = newValue
我需要添加这个,在类中覆盖 class func load() self.registerSubclass() ,并在我的桥接头中添加 #import displayName
应该是 String?
类型,因为 objectForKey(..)
可能返回 nil?【参考方案3】:
Swift 1.2
首先:创建一个swift文件并定义子类。不要忘记导入 Parse! (例如盔甲)
import Foundation
import Parse
class Armor: PFObject, PFSubclassing
// MARK: - PFSubclassing
override class func initialize()
struct Static
static var onceToken: dispatch_once_t = 0;
dispatch_once(&Static.onceToken)
self.registerSubclass()
class func parseClassName() -> String
return "Armor"
// MARK: - Parse Core Properties
@NSManaged var displayName: String?
注意:您可以将属性定义为可选项。 Parse Core Manager 中的每个“未定义”值都将被转换为“nil”。
第二:在你的AppDelegate.swift中注册所有子类。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
// Override point for customization after application launch.
// MARK: - Parse Setup
Parse.setApplicationId("YOUR_ID", clientKey: "YOUR_KEY")
// MARK: - Parse Register Subclasses
Armor.registerSubclass()
return true
【讨论】:
这符合 Parse 文档。您知道使用@Andrew Toth anshwer 是否有任何副作用? 如果在AppDelegate注册,可以去掉静态init注册码。根据我的经验,静态初始化代码——即使它在官方文档中——也会导致问题。所以我建议在 AppDelegate 中显式注册子类。 你还记得你遇到过什么样的问题吗?我刚刚找到了这个线程,试图解决一个问题,因为我的程序一直锁定在 loginWithUsernameInBackground() 中间的某个地方。如果我注释掉了似乎解决问题的initialize()方法。【参考方案4】:原型是正确的。截至目前,它不适用于动态属性,但代码示例不包含 Parse 推荐的 registerSubclass,因此代码应该像这样包含它:
class Armor : PFObject, PFSubclassing
@NSManaged var displayName: String
override class func load()
self.registerSubclass()
class func parseClassName() -> String!
return "Armor"
var armor = Armor.object()
armor.displayName = "Iron Clad"
(请注意,“覆盖”是必需的,但 Parse 文档中缺少。)
【讨论】:
在 Swift 2 及更高版本中不允许覆盖load
。【参考方案5】:
我遇到了同样的问题,但我应该注意你的类定义应该更像这样:
class Armor : PFObject, PFSubclassing
var displayName: String
class func parseClassName() -> String!
return "Armor"
var armor = Armor()
armor.displayName = "Iron Clad"
我尝试了一些不同的方法,但都没有成功。 Parse SDK 似乎还不支持这一点,请记住,Parse iOS SDK 的当前版本早于 swift 公告。听起来他们正在努力为即将发布的版本提供更好的快速支持。
相反,您仍然可以创建 PFObject 子类(就像您所做的那样)并使用 .getObjectForKey("displayName")
访问数据,或者编写您自己的类方法来访问这些数据。最大的缺失实际上只是 SDK 通常为您创建的一些便利方法。
【讨论】:
以上是关于在 Swift 中子类化 PFObject的主要内容,如果未能解决你的问题,请参考以下文章
想知道如何以编程方式在 swift 3.0 中对 UITableViewCell 进行子类化?
子类化 NSControl,在 Swift 中不调用 IBAction
将 NSManagedObject 子类化 Core Data 对象打印到控制台在 Swift 中返回空行