Swift相等需要ObjectIdentifier吗?

时间:2017-05-27 10:09:55

标签: ios swift skspritenode sknode

我们有一个自定义Swift类的多个实例,它继承自SKSpriteNode,并且能够正确执行以下代码(对于这个问题大致简化):

let instance1 = CustomClass()
let instance2 = CustomClass()
let instance3 = CustomClass()
let instance4 = CustomClass()

let array1 = [instance1, instance2]
let array2 = [instance3, instance4]

func check(testInstance: CustomClass) -> Bool {
   return array1.filter({ $0 == testInstance }).count > 0
}

check(testInstance: instance3)

换句话说,执行check(testInstance: instance3)按预期返回false

但是,我们进行了一系列更改,check停止了工作。

CustomClass未实施Equatable协议。我们只想检测唯一的实例。

它只在我们使用ObjectIdentifier时开始工作,这意味着函数已更改为:

func check(testInstance: CustomClass) -> Bool {
   return array1.filter({ ObjectIdentifier($0) == ObjectIdentifier(testInstance) }).count > 0
}

为什么需要ObjectIdentifier,何时应该将它用于对象相等?

这是用Swift 3编写的。

1 个答案:

答案 0 :(得分:2)

  

为什么需要ObjectIdentifier,何时应该将它用于对象相等?

在这种情况下,您不需要使用ObjectIdentifier来执行身份比较,您只需使用身份运算符===代替Martin says here,对于类实例,相当于使用ObjectIdentifier' s ==重载:

func check(testInstance: CustomClass) -> Bool {
    return array1.contains(where: { $0 === testInstance })
}

另请注意,我们使用contains(where:)而不是filter{...}.count > 0,因为前者会在找到匹配元素时发生短路,而后者会评估整个序列(并创建不必要的中间数组) )。

直接使用==执行对象的身份比较可能已经有效,因为CustomClass最终继承自NSObject,这符合Equatable通过定义调用an == overloadisEqual(_:)isEqual(_:),默认情况下执行身份比较。

但是一般情况下,这应该依赖 - 可以覆盖Equatable的实现,以基于属性值而不是标识执行比较。此外,语义==要求==的实现基于所比较实例的可见方面(即属性值)。

来自the documentation

  

平等意味着可替代性 - 任何两个比较的实例   同样可以在任何依赖于它们的代码中互换使用   值。为了保持可替代性,Equatable运算符应该考虑到   帐户==类型的所有可见方面。

因此,在您的课程中使用ObjectIdentifier进行身份比较从来都不正确,即使它最初可能有效。

至于应该使用===的时候,你真的应该永远不需要只是来进行身份比较。对于类,您应该使用ObjectIdentifier运算符,对于元类型,您应该只使用专门为它们定义的==重载(因为在这种情况下,身份恰好相等,因为每个新的元类型实例是独一无二的。)

hashValue的主要用途实际上是它的Dictionary实现,它是从它初始化的东西的指针值派生而来的。这可能很有用,例如,允许元类型为Array ( [0] => WC_Memberships_User_Membership Object ( [id] => 148489 [plan_id] => 148071 [plan] => WC_Memberships_Membership_Plan Object ( [id] => 148071 [name] => Groups **[slug] => groups** [post] => WP_Post Object ( [ID] => 148071 [post_author] => 1 [post_date] => 2017-05-12 11:15:21 [post_date_gmt] => 2017-05-12 10:15:21 [post_content] => [post_title] => Groups [post_excerpt] => [post_status] => publish [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => groups [to_ping] => [pinged] => [post_modified] => 2017-05-12 11:48:07 [post_modified_gmt] => 2017-05-12 10:48:07 [post_content_filtered] => [post_parent] => 0 [guid] => http://dev3.benefacto.org/?post_type=wc_membership_plan&p=148071 [menu_order] => 0 [post_type] => wc_membership_plan [post_mime_type] => [comment_count] => 0 [filter] => raw ) [access_method_meta:protected] => _access_method [default_access_method:protected] => unlimited [access_length_meta:protected] => _access_length [access_start_date_meta:protected] => _access_start_date [access_end_date_meta:protected] => _access_end_date [product_ids_meta:protected] => _product_ids [members_area_meta:protected] => _members_area_sections [email_content_meta:protected] => _email_content [rules:WC_Memberships_Membership_Plan:private] => Array ( ) ) [user_id] => 12312800 [status] => wcm-active [post] => WP_Post Object ( [ID] => 148489 [post_author] => 12312800 [post_date] => 2017-05-28 00:04:02 [post_date_gmt] => 2017-05-27 23:04:02 [post_content] => [post_title] => Auto Draft [post_excerpt] => [post_status] => wcm-active [comment_status] => closed [ping_status] => closed [post_password] => um_592a05dbb3501 [post_name] => auto-draft-2 [to_ping] => [pinged] => [post_modified] => 2017-05-28 00:04:02 [post_modified_gmt] => 2017-05-27 23:04:02 [post_content_filtered] => [post_parent] => 148071 [guid] => http://dev3.benefacto.org/?post_type=wc_user_membership&p=148489 [menu_order] => 0 [post_type] => wc_user_membership [post_mime_type] => [comment_count] => 0 [filter] => raw ) [product:WC_Memberships_User_Membership:private] => [type:protected] => manually-assigned [start_date_meta:protected] => _start_date [end_date_meta:protected] => _end_date [cancelled_date_meta:protected] => _cancelled_date [paused_date_meta:protected] => _paused_date [paused_intervals_meta:protected] => _paused_intervals [product_id_meta:protected] => _product_id [order_id_meta:protected] => _order_id [previous_owners_meta:protected] => _previous_owners ) [1] => WC_Memberships_User_Membership Object ( [id] => 148483 [plan_id] => 148169 [plan] => WC_Memberships_Membership_Plan Object ( [id] => 148169 [name] => London **[slug] => london** [post] => WP_Post Object ( [ID] => 148169 [post_author] => 1 [post_date] => 2017-05-14 11:12:52 [post_date_gmt] => 2017-05-14 10:12:52 [post_content] => [post_title] => London [post_excerpt] => [post_status] => publish [comment_status] => closed [ping_status] => closed [post_password] => [post_name] => london [to_ping] => [pinged] => [post_modified] => 2017-05-15 18:17:18 [post_modified_gmt] => 2017-05-15 17:17:18 [post_content_filtered] => [post_parent] => 0 [guid] => http://dev3.benefacto.org/?post_type=wc_membership_plan&p=148169 [menu_order] => 0 [post_type] => wc_membership_plan [post_mime_type] => [comment_count] => 0 [filter] => raw ) [access_method_meta:protected] => _access_method [default_access_method:protected] => unlimited [access_length_meta:protected] => _access_length [access_start_date_meta:protected] => _access_start_date [access_end_date_meta:protected] => _access_end_date [product_ids_meta:protected] => _product_ids [members_area_meta:protected] => _members_area_sections [email_content_meta:protected] => _email_content [rules:WC_Memberships_Membership_Plan:private] => Array ( ) ) [user_id] => 12312800 [status] => wcm-active [post] => WP_Post Object ( [ID] => 148483 [post_author] => 12312800 [post_date] => 2017-05-24 15:34:16 [post_date_gmt] => 2017-05-24 14:34:16 [post_content] => [post_title] => [post_excerpt] => [post_status] => wcm-active [comment_status] => open [ping_status] => closed [post_password] => um_592599e82db15 [post_name] => 148483 [to_ping] => [pinged] => [post_modified] => 2017-05-24 15:34:16 [post_modified_gmt] => 2017-05-24 14:34:16 [post_content_filtered] => [post_parent] => 148169 [guid] => http://dev3.benefacto.org/?post_type=wc_user_membership&p=148483 [menu_order] => 0 [post_type] => wc_user_membership [post_mime_type] => [comment_count] => 0 [filter] => raw ) [product:WC_Memberships_User_Membership:private] => [type:protected] => manually-assigned [start_date_meta:protected] => _start_date [end_date_meta:protected] => _end_date [cancelled_date_meta:protected] => _cancelled_date [paused_date_meta:protected] => _paused_date [paused_intervals_meta:protected] => _paused_intervals [product_id_meta:protected] => _product_id [order_id_meta:protected] => _order_id [previous_owners_meta:protected] => _previous_owners ) ) 个键(比较Make a Swift dictionary where the key is "Type"?)。