iOS 10 - NSKeyValueObservation crash on deinit
Tag : swift , By : user186876
Date : March 29 2020, 07:55 AM
wish of those help Updated on 2019/10/16 This seems to still happen on iOS 10.3 with Xcode 11 and Swift 5.1, I created a sample project to test it by using code from SR-5752. // Environment: Xcode 11.1, Swift 5.1, iOS 10.3
deinit {
if #available(iOS 11.0, *) {} else if let observer = observer {
removeObserver(observer, forKeyPath: "foo")
}
}
// Environment: Xcode 11.1, Swift 5.1, iOS 10.3
deinit {
// Also tried only either one, no luck
self.observer?.invalidate()
self.observer = nil
}
|
Swift iOS -View Controller deinit runs when adding it to a new keyWindow
Date : March 29 2020, 07:55 AM
I hope this helps . I got the answer from this reddit keyWindow.rootViewController = redVC
|
Avoid crash when lazy var referencing self is accessed for the first time during deinit
Tag : swift , By : arbeitandy
Date : March 29 2020, 07:55 AM
I hope this helps . I am experiencing a crash related to lazy vars in Swift. The cause of the crash is straightforward to understand, but I don't know of a good way to prevent it without losing the advantages that I gain by using the lazy var. , I just created of what you said like below: protocol Hello {
func thisGetsCalledSometimes()
}
class MyService {
var delegate: Hello?
init(key: String) {
debugPrint("Init")
}
func start() {
debugPrint("Service Started")
}
func stop() {
debugPrint("Service Stopped")
}
}
class MyClass: Hello {
lazy var service: MyService = {
// To init and configure this service,
// we need to reference `self`.
let service = MyService(key: "") // Just pretend key exists :)
service.delegate = self
return service
}()
func thisGetsCalledSometimes() {
// Calling this function causes the lazy var to
// get initialised.
self.service.start()
}
deinit {
// If `thisGetsCalledSometimes` was NOT called,
// this crashes because the initialising closure
// for `service` references `self`.
self.service.stop()
}
}
"Init"
"Service Stopped"
import UIKit
// Stuff to create a view stack:
class ViewController: UINavigationController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let firstController = FirstController()
let navigationController = UINavigationController(rootViewController: firstController)
self.present(navigationController, animated: false, completion: nil)
}
}
class FirstController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
button.setTitle("Next screen", for: .normal)
button.addTarget(self, action: #selector(onNextScreen), for: .touchUpInside)
self.view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
@objc func onNextScreen() {
let secondController = SecondController()
self.navigationController?.pushViewController(secondController, animated: true)
}
}
// The service and view controller where the crash happens:
protocol ServiceDelegate: class {
func service(_ service: Service, didReceive value: Int)
}
class Service {
weak var delegate: ServiceDelegate?
func start() {
print("Starting")
self.delegate?.service(self, didReceive: 0)
}
func stop() {
print("Stopping")
}
deinit {
delegate = nil
}
}
class SecondController: UIViewController {
private var isServiceAvailable: Bool = false
private lazy var service: Service = {
let service = Service()
service.delegate = self
//Make the service available
self.isServiceAvailable = true
return service
}()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// service.start() // <- Comment/uncomment to toggle crash
}
deinit {
if self.isServiceAvailable {
self.service.stop()
}
}
}
extension SecondController: ServiceDelegate {
func service(_ service: Service, didReceive value: Int) {
print("Value: \(value)")
}
}
|
AVAudioSequencer Causes Crash on Deinit/Segue: 'required condition is false: outputNode'
Date : March 29 2020, 07:55 AM
I wish this helpful for you This crash can be confusing, and may also output no error message whatsoever to the console if the sequencer's content hasn't been loaded yet. Very unhelpful! The AVAudioSequencer is indeed the cause of the issue. To fix it, make the sequencer an implicitly unwrapped optional (i.e. add ! to its type) and add explicit instructions to stop & remove it during deinit, before the rest of the object is deinitialized. class TestAudioClass {
private var audioEngine: AVAudioEngine
private var sampler: AVAudioUnitSampler
private var sequencer: AVAudioSequencer!
init() {
self.audioEngine = AVAudioEngine()
self.sampler = AVAudioUnitSampler()
audioEngine.attach(sampler)
audioEngine.connect(sampler, to: audioEngine.mainMixerNode, format: nil)
self.sequencer = AVAudioSequencer(audioEngine: audioEngine)
if let fileURL = Bundle.main.url(forResource: "TestMusic", withExtension: "mid") {
do {
try sequencer.load(from: fileURL, options: AVMusicSequenceLoadOptions())
} catch {
print("Error loading sequencer: \(error.localizedDescription)")
}
}
sequencer.prepareToPlay()
}
deinit {
sequencer.stop()
sequencer = nil
}
}
|
WPF DataGrid, application crash when adding a row
Date : March 29 2020, 07:55 AM
|