我尝试使用 Leaks from Instrument 检查我的应用程序是否存在内存泄漏。事实证明,泄漏指出内存泄漏是在我的扩展:日期。扩展函数在 swiftUI 中的 View 结构内用于 @Published 日期:来自我的 viewModel 的 Date 属性。难道我做错了什么?我该怎么做才能在扩展中没有强引用?这是我的扩展:
extension Date {
func toString(withFormat customFormat: String = "dd MMM YYYY") -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = customFormat
return dateFormatter.string(from: self)
}
}
这是具有日期作为属性的结构:
struct Article: Codable, Hashable {
let source: Source?
let title: String?
let author: String?
let description: String?
let url: String?
let urlToImage: String?
let publishedAt: Date?
let content: String?
}
我的 ViewModel 有文章数组:
class NewsListViewModel: ObservableObject {
@Published var searchedArticles = [Article]()
@Published var tabsArticles = [Tabs : [Article]] ()
@Published var isSearching = false
@Published var searchText = ""
@Published var selectedTab = Tabs.general
@Published var error: Error?
}
我的主要列表视图:
struct NewsList: View {
@ObservedObject var viewModel: NewsListViewModel
var body: some View {
NavigationView {
//.....//
ScrollableNewsListView(articles: articles, category: viewModel.selectedTab.rawValue, checkLastCellAction: checkActionForLastCell)
//.....//
}
}
}
可漫步视图:
private struct ScrollableNewsListView: View {
var articles: [Article]
var body: some View {
//.....//
ForEach(articles.indices, id: \.self) { index in
NewsCell(article: articles[index])
.onAppear {
checkLastCellAction(index)
//checkActionForLastCell(index: index)
}
}
//.....//
}
}
我在 LazyVStack 中使用的 cellView:
private struct NewsCell: View {
var article: Article
var body: some View {
VStack(alignment: .leading, spacing: 10) {
HStack {
URLImage(url: imageURL)
.frame(width: 50, height: 50)
.cornerRadius(25)
VStack(alignment: .leading) {
Text(article.author ?? "news_details_unknown_author".localized)
Text(dateString)// <-------- HERE I USE MY DateString that calls .toString() from Date extension
.font(.SFDisplayRegularFont(with: 12))
.foregroundColor(.gray)
}
Spacer()
}
}.padding(.all, 15)
.background(Color.newsCellBackground)
.cornerRadius(10)
}
var dateString: String {
guard let date = article.publishedAt else { return ""}
return date.toString()//<------------ Date.toString()
}
var title: String {
article.title ?? ""
}
}