I'm not sure exactly how class declarations interact with the scope of a
do{ } statement. I declare a new static function inside your do{ } scope
and it works fine, but something about the mapping of `==` and `!=` to
`isEqual` in NSObject seems to be confused by the scope of the do{ } block.
I'm not sure what the use case is for declaring a class inside a do{ }
block, but it seems like a bug with SNObject operator mapping:
//: Playground - noun: a place where people can play
import UIKit
do{
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func testStatic(_ object: Foo) {
print(object.name)
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
public static func !=(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name != rhs.name
}
override func isEqual(_ object: Any?) -> Bool {
print("in isEqual")
guard let object = object as? Foo else { return false }
let _ = super.isEqual(object)
if self.name == object.name {
return true
}
return false
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true
print(a != b) // false
Foo.testStatic(a) // bar
}
output is:
in isEqual
true
in isEqual
false
bar
For the record, enclosing just the statements *outside* the class
declaration in a do{ } block works as expected:
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
public static func !=(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name != rhs.name
}
override func isEqual(_ object: Any?) -> Bool {
print("in isEqual")
guard let object = object as? Foo else { return false }
let _ = super.isEqual(object)
if self.name == object.name {
return true
}
return false
}
}
do{
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true
print(a != b) // false
}
output:
true
false
···
On Tue, Apr 18, 2017 at 8:07 PM, Zhao Xin <owenzx@gmail.com> wrote:
Just put your code in to a do-block. The result will be opposite.
do {
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
public static func !=(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name != rhs.name
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true, now false
print(a != b) // false, now true
}
Zhaoxin
On Wed, Apr 19, 2017 at 11:04 AM, Nate Birkholz <nbirkholz@gmail.com> > wrote:
Your issue seems to be that you created a custom implementation for the
`==` operator but not one for the `!=` operator. If I add a custom
implementation for `!=` I get the results you expected. Tthe default
implementation of NSObject's `isEqual` is a test for identity, like the
`===` in Swift. So when you ask "is `a` NOT the same object in memory as
`b`?" the object returns "true" because they are indeed not the same object.
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
public static func !=(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name != rhs.name
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true
print(a != b) // false
On Tue, Apr 18, 2017 at 7:33 PM, Zhao Xin via swift-users < >> swift-users@swift.org> wrote:
Sample 1: both `==` and `!=` is true.
import Foundation
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true
print(a != b) // true
Sample 2: Add above code to a do-block, behavior changes to expect
do {
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // false
print(a != b) // true
}
Sample 3: A little investigation shows that `==` didn't call NSObject's `
func isEqual(_ object: Any?) -> Bool` but `!=` did.
class Foo:NSObject {
let name:String
init(name:String) {
self.name = name
}
public static func ==(lhs: Foo, rhs: Foo) -> Bool {
guard type(of:lhs) == type(of:rhs) else { return false }
return lhs.name == rhs.name
}
override func isEqual(to object: Any?) -> Bool {
print("111")
return super.isEqual(to: object)
}
override func isEqual(_ object: Any?) -> Bool {
print("2222")
return super.isEqual(object)
}
}
let a = Foo(name: "bar")
let b = Foo(name: "bar")
print(a == b) // true
print(a != b) // 2222, true
print(!(a == b)) // false
So I am wondering what is the future? Will we keep on using `isEqual(_
object: Any?)` with class that inherits `NSObject`, or we are trying
to drop it?
Xcode 8.3.1 (8E1000a), 3.1 (swiftlang-802.0.51 clang-802.0.41), macOS 10.12.4
(16E195)
Zhaoxin
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users
--
Nate Birkholz
--
Nate Birkholz