Skip to content

Commit 1615d3c

Browse files
authored
Fix WeakBox hash stability (#218)
1 parent c9e6c37 commit 1615d3c

File tree

6 files changed

+55
-41
lines changed

6 files changed

+55
-41
lines changed

.pubnub.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
---
22
name: swift
33
scm: github.com/pubnub/swift
4-
version: "9.2.2"
4+
version: "9.2.3"
55
schema: 1
66
changelog:
7+
- date: 2025-07-29
8+
version: 9.2.3
9+
changes:
10+
- type: bug
11+
text: "Fix WeakBox hash stability."
712
- date: 2025-07-17
813
version: 9.2.2
914
changes:
@@ -698,7 +703,7 @@ sdks:
698703
- distribution-type: source
699704
distribution-repository: GitHub release
700705
package-name: PubNub
701-
location: https://github.com/pubnub/swift/archive/refs/tags/9.2.2.zip
706+
location: https://github.com/pubnub/swift/archive/refs/tags/9.2.3.zip
702707
supported-platforms:
703708
supported-operating-systems:
704709
macOS:

PubNub.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4031,7 +4031,7 @@
40314031
"@loader_path/Frameworks",
40324032
);
40334033
MACOSX_DEPLOYMENT_TARGET = 10.15;
4034-
MARKETING_VERSION = 9.2.2;
4034+
MARKETING_VERSION = 9.2.3;
40354035
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
40364036
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
40374037
MTL_FAST_MATH = YES;
@@ -4082,7 +4082,7 @@
40824082
"@loader_path/Frameworks",
40834083
);
40844084
MACOSX_DEPLOYMENT_TARGET = 10.15;
4085-
MARKETING_VERSION = 9.2.2;
4085+
MARKETING_VERSION = 9.2.3;
40864086
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
40874087
MTL_ENABLE_DEBUG_INFO = NO;
40884088
MTL_FAST_MATH = YES;
@@ -4190,7 +4190,7 @@
41904190
"@loader_path/Frameworks",
41914191
);
41924192
MACOSX_DEPLOYMENT_TARGET = 10.15;
4193-
MARKETING_VERSION = 9.2.2;
4193+
MARKETING_VERSION = 9.2.3;
41944194
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
41954195
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
41964196
MTL_FAST_MATH = YES;
@@ -4243,7 +4243,7 @@
42434243
"@loader_path/Frameworks",
42444244
);
42454245
MACOSX_DEPLOYMENT_TARGET = 10.15;
4246-
MARKETING_VERSION = 9.2.2;
4246+
MARKETING_VERSION = 9.2.3;
42474247
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
42484248
MTL_ENABLE_DEBUG_INFO = NO;
42494249
MTL_FAST_MATH = YES;
@@ -4364,7 +4364,7 @@
43644364
"@loader_path/Frameworks",
43654365
);
43664366
MACOSX_DEPLOYMENT_TARGET = 10.15;
4367-
MARKETING_VERSION = 9.2.2;
4367+
MARKETING_VERSION = 9.2.3;
43684368
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
43694369
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
43704370
MTL_FAST_MATH = YES;
@@ -4416,7 +4416,7 @@
44164416
"@loader_path/Frameworks",
44174417
);
44184418
MACOSX_DEPLOYMENT_TARGET = 10.15;
4419-
MARKETING_VERSION = 9.2.2;
4419+
MARKETING_VERSION = 9.2.3;
44204420
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
44214421
MTL_ENABLE_DEBUG_INFO = NO;
44224422
MTL_FAST_MATH = YES;
@@ -4896,7 +4896,7 @@
48964896
"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
48974897
);
48984898
MACOSX_DEPLOYMENT_TARGET = 10.15;
4899-
MARKETING_VERSION = 9.2.2;
4899+
MARKETING_VERSION = 9.2.3;
49004900
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14";
49014901
OTHER_CFLAGS = "$(inherited)";
49024902
OTHER_LDFLAGS = "$(inherited)";
@@ -4939,7 +4939,7 @@
49394939
"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
49404940
);
49414941
MACOSX_DEPLOYMENT_TARGET = 10.15;
4942-
MARKETING_VERSION = 9.2.2;
4942+
MARKETING_VERSION = 9.2.3;
49434943
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14";
49444944
OTHER_CFLAGS = "$(inherited)";
49454945
OTHER_LDFLAGS = "$(inherited)";

PubNubSwift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'PubNubSwift'
3-
s.version = '9.2.2'
3+
s.version = '9.2.3'
44
s.homepage = 'https://github.com/pubnub/swift'
55
s.documentation_url = 'https://www.pubnub.com/docs/swift-native/pubnub-swift-sdk'
66
s.authors = { 'PubNub, Inc.' => '[email protected]' }

Sources/PubNub/Helpers/Constants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public enum Constant {
5757

5858
static let pubnubSwiftSDKName: String = "PubNubSwift"
5959

60-
static let pubnubSwiftSDKVersion: String = "9.2.2"
60+
static let pubnubSwiftSDKVersion: String = "9.2.3"
6161

6262
static let appBundleId: String = {
6363
if let info = Bundle.main.infoDictionary,

Sources/PubNub/Helpers/WeakBox.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,22 @@ import Foundation
1414
final class WeakBox<Element>: Hashable where Element: AnyObject, Element: Hashable {
1515
/// The stored element
1616
weak var underlying: Element?
17+
/// The hash value of the underlying element
18+
private let underlyingHashValue: Int
1719

18-
init(_ value: Element?) {
20+
init(_ value: Element) {
1921
underlying = value
22+
var hasher = Hasher()
23+
value.hash(into: &hasher)
24+
underlyingHashValue = hasher.finalize()
2025
}
2126

2227
static func == (lhs: WeakBox<Element>, rhs: WeakBox<Element>) -> Bool {
23-
return lhs.underlying == rhs.underlying
28+
return lhs.underlyingHashValue == rhs.underlyingHashValue
2429
}
2530

2631
func hash(into hasher: inout Hasher) {
27-
hasher.combine(underlying)
32+
hasher.combine(underlyingHashValue)
2833
}
2934
}
3035

Tests/PubNubTests/Helpers/WeakBoxTests.swift

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,6 @@ class WeakBoxTests: XCTestCase {
3535
}
3636
}
3737

38-
func testWeakBox_ReleaseWeakRef() {
39-
let expectation = self.expectation(description: "testWeakBoxRetain")
40-
41-
var testObject: DeinitTest? = DeinitTest(value: "Hello")
42-
testObject?.deinitClosure = {
43-
expectation.fulfill()
44-
}
45-
46-
let weakBox = WeakBox(testObject)
47-
48-
testObject = nil
49-
50-
XCTAssertNil(weakBox.underlying)
51-
52-
wait(for: [expectation], timeout: 1.0)
53-
}
54-
5538
func testWeakBox_ContainsStrongRef() {
5639
let weakBox = WeakBox(strongValue)
5740

@@ -72,15 +55,13 @@ class WeakBoxTests: XCTestCase {
7255
class WeakSetTests: XCTestCase {
7356
func testAllObject() {
7457
let testObjects: [NSString] = ["Hello"]
75-
7658
let weakSet = WeakSet<NSString>(testObjects)
7759

7860
XCTAssertEqual(weakSet.allObjects, testObjects)
7961
}
8062

8163
func testCount() {
8264
let testObjects: [NSString] = ["Hello"]
83-
8465
let weakSet = WeakSet<NSString>(testObjects)
8566

8667
XCTAssertEqual(weakSet.count, testObjects.count)
@@ -94,11 +75,8 @@ class WeakSetTests: XCTestCase {
9475
XCTAssertEqual(weakSet.count, testObjects.count)
9576

9677
weakSet.update(newObject)
97-
9878
XCTAssertEqual(weakSet.count, testObjects.count + 1)
99-
10079
weakSet.update(newObject)
101-
10280
XCTAssertEqual(weakSet.count, testObjects.count + 1)
10381
}
10482

@@ -109,9 +87,7 @@ class WeakSetTests: XCTestCase {
10987
var weakSet = WeakSet<NSString>(testObjects)
11088

11189
XCTAssertEqual(weakSet.count, testObjects.count)
112-
11390
weakSet.remove(testObject)
114-
11591
XCTAssertTrue(weakSet.isEmpty)
11692
}
11793

@@ -120,11 +96,39 @@ class WeakSetTests: XCTestCase {
12096
let testObjects: [NSString] = [testObject]
12197

12298
var weakSet = WeakSet<NSString>(testObjects)
123-
12499
XCTAssertEqual(weakSet.count, testObjects.count)
125-
126100
weakSet.removeAll()
101+
XCTAssertTrue(weakSet.isEmpty)
102+
}
103+
104+
func testInsertingEqualObjects() {
105+
let firstObject: NSString = "Hello"
106+
let secondObject: NSString = "Hello"
127107

108+
var weakSet = WeakSet<NSString>([firstObject])
109+
XCTAssertEqual(weakSet.count, 1)
110+
weakSet.update(secondObject)
111+
XCTAssertEqual(weakSet.count, 1)
112+
}
113+
114+
func testRemovingEqualObjects() {
115+
let firstObject: NSString = "Hello"
116+
let secondObject: NSString = "Hello"
117+
118+
var weakSet = WeakSet<NSString>([firstObject])
119+
XCTAssertEqual(weakSet.count, 1)
120+
weakSet.remove(secondObject)
128121
XCTAssertTrue(weakSet.isEmpty)
129122
}
123+
124+
func testInitializingWithDuplicateObjects() {
125+
let firstObject: NSString = "Hello"
126+
let secondObject: NSString = "Hello"
127+
let thirdObject: NSString = "World"
128+
129+
let weakSet = WeakSet<NSString>([firstObject, secondObject, thirdObject])
130+
XCTAssertEqual(weakSet.count, 2)
131+
XCTAssertTrue(weakSet.contains { $0 == "Hello" })
132+
XCTAssertTrue(weakSet.contains { $0 == "World" })
133+
}
130134
}

0 commit comments

Comments
 (0)