Skip to content

Commit

Permalink
Merge pull request #712 from pakko972/automatic-ios-memory-management
Browse files Browse the repository at this point in the history
Automatic ios memory management
  • Loading branch information
groue authored Feb 29, 2020
2 parents a7d02b9 + c534193 commit fd029ff
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
### New

- [#706](https://github.com/groue/GRDB.swift/pull/706): Enhance SQLLiteral and SQL interpolation again
- [#712](https://github.com/groue/GRDB.swift/pull/712) by [@pakko972](https://github.com/pakko972): Automatic iOS memory management

### Breaking Change

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("db.sqlite")
dbQueue = try AppDatabase.openDatabase(atPath: databaseURL.path)

// Be a nice iOS citizen, and don't consume too much memory
// See https://github.com/groue/GRDB.swift/blob/master/README.md#memory-management
dbQueue.setupMemoryManagement(in: application)
}
}
25 changes: 15 additions & 10 deletions GRDB/Core/DatabasePool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ public final class DatabasePool: DatabaseWriter {

var databaseSnapshotCount = LockedBox(value: 0)

#if os(iOS)
private weak var application: UIApplication?
#endif

// MARK: - Database Information

/// The path to the database.
Expand Down Expand Up @@ -138,10 +134,16 @@ public final class DatabasePool: DatabaseWriter {
}

setupSuspension()

// Be a nice iOS citizen, and don't consume too much memory
// See https://github.com/groue/GRDB.swift/#memory-management
#if os(iOS)
setupAutomaticMemoryManagement()
#endif
}

deinit {
// Undo job done in setupMemoryManagement()
// Undo job done in setupAutomaticMemoryManagement()
//
// https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11Error
// Explicit unregistration is required before iOS 9 and OS X 10.11.
Expand Down Expand Up @@ -194,8 +196,6 @@ extension DatabasePool {
///
/// This method blocks the current thread until all database accesses
/// are completed.
///
/// See also setupMemoryManagement(application:)
public func releaseMemory() {
// Release writer memory
writer.sync { $0.releaseMemory() }
Expand All @@ -207,15 +207,20 @@ extension DatabasePool {


#if os(iOS)
// swiftlint:disable:next line_length
@available(*, deprecated, message: "Memory management is now enabled by default. This deprecated method does nothing.")
public func setupMemoryManagement(in application: UIApplication) {
// No op.
}

/// Listens to UIApplicationDidEnterBackgroundNotification and
/// UIApplicationDidReceiveMemoryWarningNotification in order to release
/// as much memory as possible.
///
/// - param application: The UIApplication that will start a background
/// task to let the database pool release its memory when the application
/// enters background.
public func setupMemoryManagement(in application: UIApplication) {
self.application = application
private func setupAutomaticMemoryManagement() {
let center = NotificationCenter.default
center.addObserver(
self,
Expand All @@ -231,7 +236,7 @@ extension DatabasePool {

@objc
private func applicationDidEnterBackground(_ notification: NSNotification) {
guard let application = application else {
guard let application = notification.object as? UIApplication else {
return
}

Expand Down
24 changes: 15 additions & 9 deletions GRDB/Core/DatabaseQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import UIKit
/// A DatabaseQueue serializes access to an SQLite database.
public final class DatabaseQueue: DatabaseWriter {
private var writer: SerializedDatabase
#if os(iOS)
private weak var application: UIApplication?
#endif

// MARK: - Configuration

Expand Down Expand Up @@ -43,6 +40,12 @@ public final class DatabaseQueue: DatabaseWriter {
defaultLabel: "GRDB.DatabaseQueue")

setupSuspension()

// Be a nice iOS citizen, and don't consume too much memory
// See https://github.com/groue/GRDB.swift/#memory-management
#if os(iOS)
setupAutomaticMemoryManagement()
#endif
}

/// Opens an in-memory SQLite database.
Expand All @@ -62,7 +65,7 @@ public final class DatabaseQueue: DatabaseWriter {
}

deinit {
// Undo job done in setupMemoryManagement()
// Undo job done in setupAutomaticMemoryManagement()
//
// https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11Error
// Explicit unregistration is required before iOS 9 and OS X 10.11.
Expand All @@ -77,22 +80,25 @@ extension DatabaseQueue {
/// Free as much memory as possible.
///
/// This method blocks the current thread until all database accesses are completed.
///
/// See also setupMemoryManagement(application:)
public func releaseMemory() {
writer.sync { $0.releaseMemory() }
}

#if os(iOS)
// swiftlint:disable:next line_length
@available(*, deprecated, message: "Memory management is now enabled by default. This deprecated method does nothing.")
public func setupMemoryManagement(in application: UIApplication) {
// No op.
}

/// Listens to UIApplicationDidEnterBackgroundNotification and
/// UIApplicationDidReceiveMemoryWarningNotification in order to release
/// as much memory as possible.
///
/// - param application: The UIApplication that will start a background
/// task to let the database queue release its memory when the application
/// enters background.
public func setupMemoryManagement(in application: UIApplication) {
self.application = application
private func setupAutomaticMemoryManagement() {
let center = NotificationCenter.default
center.addObserver(
self,
Expand All @@ -108,7 +114,7 @@ extension DatabaseQueue {

@objc
private func applicationDidEnterBackground(_ notification: NSNotification) {
guard let application = application else {
guard let application = notification.object as? UIApplication else {
return
}

Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@ endif
TEST_ACTIONS = clean build build-for-testing test-without-building

# When adding support for an Xcode version, look for available devices with `instruments -s devices`
ifeq ($(XCODEVERSION),11.3)
ifeq ($(XCODEVERSION),11.4)
MAX_SWIFT_VERSION = 5.2
MIN_SWIFT_VERSION = 4.2
MAX_IOS_DESTINATION = "platform=iOS Simulator,name=iPhone 11,OS=13.4"
MIN_IOS_DESTINATION = "platform=iOS Simulator,name=iPhone 5,OS=10.3.1"
MAX_TVOS_DESTINATION = "platform=tvOS Simulator,name=Apple TV 4K,OS=13.4"
MIN_TVOS_DESTINATION = "platform=tvOS Simulator,name=Apple TV,OS=10.2"
else ifeq ($(XCODEVERSION),11.3)
MAX_SWIFT_VERSION = 5.1
MIN_SWIFT_VERSION = 4.2
MAX_IOS_DESTINATION = "platform=iOS Simulator,name=iPhone 11,OS=13.3"
Expand Down
7 changes: 1 addition & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7147,12 +7147,7 @@ This method blocks the current thread until all current database accesses are co

**The iOS operating system likes applications that do not consume much memory.**

[Database queues](#database-queues) and [pools](#database-pools) can call the `releaseMemory` method for you, when application receives memory warnings, and when application enters background: call the `setupMemoryManagement` method after creating the queue or pool instance:

```
let dbQueue = try DatabaseQueue(...)
dbQueue.setupMemoryManagement(in: UIApplication.shared)
```
[Database queues](#database-queues) and [pools](#database-pools) automatically call the `releaseMemory` method when the application receives a memory warning, and when the application enters background.


## Data Protection
Expand Down

0 comments on commit fd029ff

Please sign in to comment.