JH_EARTH
JH_EARTH

Reputation: 53

Why does the Swift identity operator "===" return true for NSNumbers?

the operator "===" should compare class references to determine if both sides are referring same object:

var objectA : NSNumber = 1
var objectB : NSNumber = 1

print(objectA === objectB)
// return true, 

so my question is NSNumber wrapped the object into the same object, how is the back-end logic of doing so.

Upvotes: 2

Views: 82

Answers (1)

jtbandes
jtbandes

Reputation: 118671

NSNumber is one of a small handful of classes which can sometimes be represented as tagged pointers (at least on Apple platforms; I don't think this applies to the open-source version of (Core)Foundation).

Basically, this means that rather than a pointer to an actual instance of a class located elsewhere in memory, the NSNumber stores its value (in this case 1) directly inside the pointer. You can see this for yourself:

import Foundation

let x: NSNumber = 1
let y: NSNumber = 2

// Tagged pointers: the number is stored inside the pointer representation.
print(Unmanaged.passUnretained(x).toOpaque())  // 0x0000000000000137
print(Unmanaged.passUnretained(y).toOpaque())  // 0x0000000000000237

class C {}
let c = C()

// Not a tagged pointer; just a regular pointer to allocated memory.
print(Unmanaged.passUnretained(c).toOpaque())  // 0x00007fb32276daa0

The same optimizations can apply to NSString and other types too. For more details, read Mike Ash's excellent in-depth blog posts:

Don't rely on this, however. It's just an implementation detail, and not all NSNumbers may be represented this way. The correct way to compare them for equality is ==.

Upvotes: 2

Related Questions