Add DeinitObserver for ParasiticTask on Darwin

This commit is contained in:
QuentinJin 2018-08-26 21:49:21 +08:00
parent 3de74c73a2
commit fa17c31a88
4 changed files with 75 additions and 0 deletions

View File

@ -21,6 +21,8 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
667D2DF72132C5390071DC89 /* DeinitObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667D2DF62132C5390071DC89 /* DeinitObserver.swift */; };
667D2DF92132C95D0071DC89 /* DeinitObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667D2DF82132C95D0071DC89 /* DeinitObserverTests.swift */; };
OBJ_45 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Atomic.swift */; };
OBJ_46 /* Bucket.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Bucket.swift */; };
OBJ_47 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* Extensions.swift */; };
@ -67,6 +69,8 @@
/* Begin PBXFileReference section */
626D761B2113F9D100FCAFFE /* README.zh_cn.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.zh_cn.md; sourceTree = "<group>"; };
667D2DF62132C5390071DC89 /* DeinitObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeinitObserver.swift; sourceTree = "<group>"; };
667D2DF82132C95D0071DC89 /* DeinitObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeinitObserverTests.swift; sourceTree = "<group>"; };
668685ED210DCC0E009305C3 /* .swift-version */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".swift-version"; sourceTree = "<group>"; };
668685EE210DCC0E009305C3 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
668685EF210DCC0E009305C3 /* .codecov.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .codecov.yml; sourceTree = "<group>"; };
@ -142,6 +146,7 @@
OBJ_10 /* Bucket.swift */,
OBJ_11 /* Extensions.swift */,
OBJ_13 /* Lock.swift */,
667D2DF62132C5390071DC89 /* DeinitObserver.swift */,
);
name = Utils;
sourceTree = "<group>";
@ -164,6 +169,7 @@
OBJ_26 /* AtomicTests.swift */,
OBJ_27 /* BucketTests.swift */,
OBJ_29 /* ExtensionsTests.swift */,
667D2DF82132C95D0071DC89 /* DeinitObserverTests.swift */,
);
name = UtilsTests;
sourceTree = "<group>";
@ -347,6 +353,7 @@
OBJ_53 /* Schedule.swift in Sources */,
OBJ_54 /* Task.swift in Sources */,
OBJ_55 /* TaskHub.swift in Sources */,
667D2DF72132C5390071DC89 /* DeinitObserver.swift in Sources */,
OBJ_56 /* Time.swift in Sources */,
OBJ_57 /* Timeline.swift in Sources */,
OBJ_59 /* Weekday.swift in Sources */,
@ -371,6 +378,7 @@
OBJ_80 /* ExtensionsTests.swift in Sources */,
OBJ_81 /* Misc.swift in Sources */,
OBJ_82 /* SchedulesTests.swift in Sources */,
667D2DF92132C95D0071DC89 /* DeinitObserverTests.swift in Sources */,
OBJ_83 /* TaskHubTests.swift in Sources */,
OBJ_84 /* TaskTests.swift in Sources */,
OBJ_86 /* XCTestManifests.swift in Sources */,

View File

@ -0,0 +1,33 @@
//
// DeinitObserver.swift
// Schedule
//
// Created by Quentin Jin on 2018/8/26.
//
import Foundation
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
class DeinitObserver<T: AnyObject> {
private weak var observed: T?
private var block: () -> Void
private init(_ block: @escaping () -> Void) {
self.block = block
}
static func observe(_ observed: T, whenDeinit: @escaping () -> Void) {
let observer = DeinitObserver(whenDeinit)
var key: Void = ()
objc_setAssociatedObject(observed, &key, observer, .OBJC_ASSOCIATION_RETAIN)
}
deinit {
block()
}
}
#endif

View File

@ -71,5 +71,11 @@ private final class ParasiticTask: Task {
onElapse(task)
}
self.parasitifer = host
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
DeinitObserver.observe(host) { [weak self] in
self?.cancel()
}
#endif
}
}

View File

@ -0,0 +1,28 @@
//
// DeinitObserverTests.swift
// ScheduleTests
//
// Created by Quentin Jin on 2018/8/26.
//
import XCTest
@testable import Schedule
final class DeinitObserverTests: XCTestCase {
func testObserver() {
var de = false
let block = {
let obj = NSObject()
DeinitObserver.observe(obj, whenDeinit: {
de = true
})
}
block()
XCTAssertTrue(de)
}
static var allTests = [
("testObserver", testObserver)
]
}