Skip to content

Commit e73e86a

Browse files
authored
Add missing unowned specifiers (#11248)
1 parent 927ae35 commit e73e86a

File tree

7 files changed

+55
-12
lines changed

7 files changed

+55
-12
lines changed

FirebaseFunctions/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 10.10.0
2+
- [fixed] Fixed potential memory leak of Functions instances. (#11248)
3+
14
# 10.0.0
25
- [fixed] Remove unnecessary and unused `encoder` and `decoder` parameters from
36
`public func call(_ data: Request) async throws -> Response` API. (#9891)

FirebaseFunctions/Sources/Internal/FunctionsComponent.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ protocol FunctionsProvider {
3636
// MARK: - Private Variables
3737

3838
/// The app associated with all functions instances in this container.
39-
private let app: FirebaseApp
39+
/// This is `unowned` instead of `weak` so it can be used without unwrapping in `functions()`
40+
private unowned let app: FirebaseApp
4041

4142
/// A map of active instances, grouped by app. Keys are FirebaseApp names and values are arrays
4243
/// containing all instances of Functions associated with the given app.

FirebaseFunctions/Tests/Unit/FunctionsTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,22 @@ class FunctionsTests: XCTestCase {
167167
}
168168
waitForExpectations(timeout: 1.5)
169169
}
170+
171+
/// Test that Functions instances get deallocated.
172+
func testFunctionsLifecycle() throws {
173+
weak var weakApp: FirebaseApp?
174+
weak var weakFunctions: Functions?
175+
try autoreleasepool {
176+
let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
177+
gcmSenderID: "00000000000000000-00000000000-000000000")
178+
options.projectID = "myProjectID"
179+
let app1 = FirebaseApp(instanceWithName: "transitory app", options: options)
180+
weakApp = try XCTUnwrap(app1)
181+
let functions = Functions(app: app1, region: "transitory-region", customDomain: nil)
182+
weakFunctions = functions
183+
XCTAssertNotNil(weakFunctions)
184+
}
185+
XCTAssertNil(weakApp)
186+
XCTAssertNil(weakFunctions)
187+
}
170188
}

FirebaseFunctions/Tests/Unit/SerializerTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class SerializerTests: XCTestCase {
198198
1 as Int32,
199199
"two",
200200
[3 as Int32, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
201-
"value": "9876543210"]],
201+
"value": "9876543210"]] as [Any],
202202
] as NSArray
203203
XCTAssertEqual(input, try serializer.encode(input) as? NSArray)
204204
}
@@ -209,23 +209,23 @@ class SerializerTests: XCTestCase {
209209
1 as Int64,
210210
"two",
211211
[3 as Int32, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
212-
"value": "9876543210"]],
212+
"value": "9876543210"]] as [Any],
213213
] as NSArray
214-
let expected = [1 as Int64, "two", [3 as Int32, 9_876_543_210 as Int64]] as NSArray
214+
let expected = [1 as Int64, "two", [3 as Int32, 9_876_543_210 as Int64] as [Any]] as NSArray
215215
XCTAssertEqual(expected, try serializer.decode(input) as? NSArray)
216216
}
217217

218218
func testEncodeMap() {
219219
let input = [
220220
"foo": 1 as Int32,
221221
"bar": "hello",
222-
"baz": [3 as Int32, 9_876_543_210 as Int64],
222+
"baz": [3 as Int32, 9_876_543_210 as Int64] as [Any],
223223
] as NSDictionary
224224
let expected = [
225225
"foo": 1,
226226
"bar": "hello",
227227
"baz": [3, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
228-
"value": "9876543210"]],
228+
"value": "9876543210"]] as [Any],
229229
] as NSDictionary
230230
let serializer = FUNSerializer()
231231
XCTAssertEqual(expected, try serializer.encode(input) as? NSDictionary)

FirebaseStorage/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 10.10.0
2+
- [fixed] Fixed potential memory leak of Storage instances. (#11248)
3+
14
# 10.7.0
25
- [added] Provide server errors via the `NSUnderlyingErrorKey`.
36

FirebaseStorage/Sources/StorageComponent.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ protocol StorageProvider {
2929
// MARK: - Private Variables
3030

3131
/// The app associated with all Storage instances in this container.
32-
private let app: FirebaseApp
32+
/// This is `unowned` instead of `weak` so it can be used without unwrapping in `storage(...)`
33+
private unowned let app: FirebaseApp
3334

3435
/// A map of active instances, grouped by app. Keys are FirebaseApp names and values are arrays
3536
/// containing all instances of Storage associated with the given app.

FirebaseStorage/Tests/Unit/StorageComponentTests.swift

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class StorageComponentTests: StorageTestHelpers {
3434

3535
/// Tests that a Storage instance can be created properly by the StorageComponent.
3636
func testStorageInstanceCreation() throws {
37-
let component = StorageComponent(app: StorageComponentTests.app)
37+
let app = try XCTUnwrap(StorageComponentTests.app)
38+
let component = StorageComponent(app: app)
3839
let storage = component.storage(for: "someBucket")
3940
XCTAssertNotNil(storage)
4041
}
@@ -61,11 +62,9 @@ class StorageComponentTests: StorageTestHelpers {
6162

6263
/// Tests that instances of Storage created are different.
6364
func testMultipleStorageInstancesCreated() throws {
65+
let app = try XCTUnwrap(StorageComponentTests.app)
6466
let registrants = NSMutableSet(array: [StorageComponent.self])
65-
let container = FirebaseComponentContainer(
66-
app: StorageComponentTests.app,
67-
registrants: registrants
68-
)
67+
let container = FirebaseComponentContainer(app: app, registrants: registrants)
6968

7069
let provider = ComponentType<StorageProvider>.instance(for: StorageProvider.self,
7170
in: container)
@@ -83,4 +82,22 @@ class StorageComponentTests: StorageTestHelpers {
8382

8483
XCTAssert(storage1 !== storage3)
8584
}
85+
86+
/// Test that Storage instances get deallocated.
87+
func testStorageLifecycle() throws {
88+
weak var weakApp: FirebaseApp?
89+
weak var weakStorage: Storage?
90+
try autoreleasepool {
91+
let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
92+
gcmSenderID: "00000000000000000-00000000000-000000000")
93+
options.projectID = "myProjectID"
94+
let app1 = FirebaseApp(instanceWithName: "transitory app", options: options)
95+
weakApp = try XCTUnwrap(app1)
96+
let storage = Storage(app: app1, bucket: "transitory bucket")
97+
weakStorage = storage
98+
XCTAssertNotNil(weakStorage)
99+
}
100+
XCTAssertNil(weakApp)
101+
XCTAssertNil(weakStorage)
102+
}
86103
}

0 commit comments

Comments
 (0)