首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI类不会DeInit

SwiftUI类不会DeInit
EN

Stack Overflow用户
提问于 2022-05-30 15:45:44
回答 1查看 164关注 0票数 0

我有一个类MapSearch,当我需要自动完成地址结果时,我会实例化它。它工作得很完美,但它从不去初始化,我也不知道为什么。

通过创建下面的文件轻松地进行测试。导航到测试页并查看控制台消息后使用后退按钮。您将看到视图模型按其应有的方式初始化和去初始化,但您将只看到MapSearch初始化。

HomeView.swift

代码语言:javascript
复制
import SwiftUI

struct HomeView: View {

    var body: some View {
        NavigationView {
            NavigationLink(destination: TestView(viewModel: TestViewModel()) {
                Text("TestView")
            }
        }
    }
}

TestView.swift

代码语言:javascript
复制
import SwiftUI

struct TestView: View {
    @StateObject var viewModel: ViewModel

    var body: some View {
        Text("Hello World")
    }
}

TestViewModel.swift

代码语言:javascript
复制
import Foundation

extension TestView {
    @MainActor
    class ViewModel: ObservableObject {
        @Published var mapSearch: MapSearch()
        init() {
            print("Test View Model Initialized")
        }
        deinit {
            print("Test View Model Deinitialized")
        }
    }
}

MapSearch.swift

代码语言:javascript
复制
import Combine
import CoreLocation
import Foundation
import MapKit

/// Uses MapKit and CoreLocation to auto-complete an address
class MapSearch: NSObject, ObservableObject {
    @Published var countryName: String = "United States"
    @Published var locationResults: [MKLocalSearchCompletion] = []
    @Published var searchTerm = ""

    private var cancellables: Set<AnyCancellable> = []

    private var searchCompleter = MKLocalSearchCompleter()
    private var currentPromise: ((Result<[MKLocalSearchCompletion], Error>) -> Void)?

    override init() {
        super.init()
        searchCompleter.delegate = self
        searchCompleter.resultTypes = MKLocalSearchCompleter.ResultType([.address])

        $searchTerm
            .debounce(for: .seconds(0.2), scheduler: RunLoop.main)
            .removeDuplicates()
            .flatMap({ (currentSearchTerm) in
                self.searchTermToResults(searchTerm: currentSearchTerm, countryName: self.countryName)
            })
            .sink(receiveCompletion: { (_) in
            }, receiveValue: { (results) in

                // Show country specific results
                self.locationResults = results.filter { $0.subtitle.contains(self.countryName) }
            })
            .store(in: &cancellables)

        print("MapSearch Initialized")
    }

    deinit {
        print("MapSearch Deinitialized")
    }

    func searchTermToResults(searchTerm: String, countryName: String) -> Future<[MKLocalSearchCompletion], Error> {
        Future { promise in
            self.searchCompleter.queryFragment = searchTerm
            self.currentPromise = promise
        }
    }
}

extension MapSearch: MKLocalSearchCompleterDelegate {
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
            currentPromise?(.success(completer.results))
        }

    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
        // deal with the error here, it will finish the Combine publisher stream
         currentPromise?(.failure(error))
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-30 16:28:48

需要对MapSearch类进行调整,以便在组合调用中添加弱自。现在它正确地发挥了作用。

以下是供参考的代码:

代码语言:javascript
复制
import Combine
import CoreLocation
import Foundation
import MapKit

/// Uses MapKit and CoreLocation to auto-complete an address
class MapSearch: NSObject, ObservableObject {
    @Published var countryName: String = "United States"
    @Published var locationResults: [MKLocalSearchCompletion] = []
    @Published var searchTerm = ""

    private var cancellables: Set<AnyCancellable> = []

    private var searchCompleter = MKLocalSearchCompleter()
    private var currentPromise: ((Result<[MKLocalSearchCompletion], Error>) -> Void)?

    override init() {
        super.init()
        searchCompleter.delegate = self
        searchCompleter.resultTypes = MKLocalSearchCompleter.ResultType([.address])

        $searchTerm
            .debounce(for: .seconds(0.2), scheduler: RunLoop.main)
            .removeDuplicates()
            .flatMap({ [weak self] (currentSearchTerm) in
                (self?.searchTermToResults(searchTerm: currentSearchTerm, countryName: self?.countryName ?? "")) ??
                Future { [weak self] promise in
                    self?.searchCompleter.queryFragment = self?.searchTerm ?? ""
                    self?.currentPromise = promise
                }
            })
            .sink(receiveCompletion: { (_) in
            }, receiveValue: { [weak self] (results) in

                // Show country specific results
                self?.locationResults = results.filter { $0.subtitle.contains(self?.countryName ?? "") }
            })
            .store(in: &cancellables)

        print("MapSearch Initialized")
    }

    deinit {
        print("MapSearch Deinitialized")
    }

    func searchTermToResults(searchTerm: String, countryName: String) -> Future<[MKLocalSearchCompletion], Error> {
        Future { [weak self] promise in
            self?.searchCompleter.queryFragment = searchTerm
            self?.currentPromise = promise
        }
    }
}

extension MapSearch: MKLocalSearchCompleterDelegate {
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
            currentPromise?(.success(completer.results))
        }

    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
        // deal with the error here, it will finish the Combine publisher stream
         currentPromise?(.failure(error))
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72436930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档