Implement pagination for history items in CoreDataManager and update HistoryView to support loading more data. Introduce new methods for fetching history items with pagination and total count, enhancing performance and user experience. Add localized strings for "Load More" functionality in multiple languages. Integrate memory monitoring in MyQrCodeApp for improved resource management.
parent
510dd6d49a
commit
a3df0ebc25
@ -0,0 +1,298 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
// MARK: - 内存监控器
|
||||||
|
class MemoryMonitor: ObservableObject {
|
||||||
|
static let shared = MemoryMonitor()
|
||||||
|
|
||||||
|
@Published var currentMemoryUsage: String = "Unknown"
|
||||||
|
@Published var memoryWarningCount: Int = 0
|
||||||
|
|
||||||
|
private var memoryCheckTimer: Timer?
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// 监听内存警告
|
||||||
|
NotificationCenter.default.addObserver(
|
||||||
|
self,
|
||||||
|
selector: #selector(handleMemoryWarning),
|
||||||
|
name: UIApplication.didReceiveMemoryWarningNotification,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// 启动内存监控
|
||||||
|
startMemoryMonitoring()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
NotificationCenter.default.removeObserver(self)
|
||||||
|
stopMemoryMonitoring()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存使用监控
|
||||||
|
|
||||||
|
/// 获取当前内存使用情况
|
||||||
|
func getMemoryUsage() -> String {
|
||||||
|
var info = mach_task_basic_info()
|
||||||
|
var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size)/4
|
||||||
|
|
||||||
|
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
|
||||||
|
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
|
||||||
|
task_info(mach_task_self_,
|
||||||
|
task_flavor_t(MACH_TASK_BASIC_INFO),
|
||||||
|
$0,
|
||||||
|
&count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if kerr == KERN_SUCCESS {
|
||||||
|
let usedMB = Double(info.resident_size) / 1024.0 / 1024.0
|
||||||
|
return String(format: "%.1f MB", usedMB)
|
||||||
|
} else {
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取内存使用详情
|
||||||
|
func getMemoryUsageDetails() -> (usedMB: Double, totalMB: Double, percentage: Double) {
|
||||||
|
var info = mach_task_basic_info()
|
||||||
|
var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size)/4
|
||||||
|
|
||||||
|
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
|
||||||
|
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
|
||||||
|
task_info(mach_task_self_,
|
||||||
|
task_flavor_t(MACH_TASK_BASIC_INFO),
|
||||||
|
$0,
|
||||||
|
&count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if kerr == KERN_SUCCESS {
|
||||||
|
let usedMB = Double(info.resident_size) / 1024.0 / 1024.0
|
||||||
|
let totalMB = Double(ProcessInfo.processInfo.physicalMemory) / 1024.0 / 1024.0
|
||||||
|
let percentage = (usedMB / totalMB) * 100.0
|
||||||
|
|
||||||
|
return (usedMB, totalMB, percentage)
|
||||||
|
} else {
|
||||||
|
return (0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存压力检查
|
||||||
|
|
||||||
|
/// 检查内存压力
|
||||||
|
func checkMemoryPressure() {
|
||||||
|
let memoryUsage = getMemoryUsage()
|
||||||
|
currentMemoryUsage = memoryUsage
|
||||||
|
|
||||||
|
print("📊 当前内存使用: \(memoryUsage)")
|
||||||
|
|
||||||
|
// 解析内存使用量
|
||||||
|
if let usage = Double(memoryUsage.replacingOccurrences(of: " MB", with: "")) {
|
||||||
|
if usage > 200 { // 超过200MB
|
||||||
|
print("⚠️ 内存使用过高,执行清理操作")
|
||||||
|
performMemoryCleanup()
|
||||||
|
} else if usage > 150 { // 超过150MB
|
||||||
|
print("⚠️ 内存使用较高,建议清理")
|
||||||
|
suggestMemoryCleanup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 执行内存清理
|
||||||
|
func performMemoryCleanup() {
|
||||||
|
print("🧹 执行内存清理操作")
|
||||||
|
|
||||||
|
// 清理图片缓存
|
||||||
|
ImageCacheManager.shared.clearCache()
|
||||||
|
|
||||||
|
// 清理临时文件
|
||||||
|
cleanupTempFiles()
|
||||||
|
|
||||||
|
// 通知其他组件进行清理
|
||||||
|
NotificationCenter.default.post(name: .memoryCleanup, object: nil)
|
||||||
|
|
||||||
|
// 强制垃圾回收
|
||||||
|
autoreleasepool {
|
||||||
|
// 执行一些内存密集型操作来触发垃圾回收
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 建议内存清理
|
||||||
|
func suggestMemoryCleanup() {
|
||||||
|
print("💡 建议执行内存清理")
|
||||||
|
|
||||||
|
// 只清理非关键缓存
|
||||||
|
ImageCacheManager.shared.clearCache()
|
||||||
|
|
||||||
|
// 通知其他组件进行轻度清理
|
||||||
|
NotificationCenter.default.post(name: .memoryCleanupSuggestion, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 临时文件清理
|
||||||
|
|
||||||
|
/// 清理临时文件
|
||||||
|
private func cleanupTempFiles() {
|
||||||
|
let tempPath = NSTemporaryDirectory()
|
||||||
|
let fileManager = FileManager.default
|
||||||
|
|
||||||
|
do {
|
||||||
|
let tempFiles = try fileManager.contentsOfDirectory(atPath: tempPath)
|
||||||
|
var cleanedCount = 0
|
||||||
|
|
||||||
|
for file in tempFiles {
|
||||||
|
let filePath = (tempPath as NSString).appendingPathComponent(file)
|
||||||
|
|
||||||
|
// 只删除图片相关的临时文件
|
||||||
|
if file.hasSuffix(".jpg") || file.hasSuffix(".png") || file.hasSuffix(".tmp") {
|
||||||
|
try fileManager.removeItem(atPath: filePath)
|
||||||
|
cleanedCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("🗑️ 清理了 \(cleanedCount) 个临时文件")
|
||||||
|
} catch {
|
||||||
|
print("❌ 清理临时文件失败: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 监控控制
|
||||||
|
|
||||||
|
/// 启动内存监控
|
||||||
|
func startMemoryMonitoring() {
|
||||||
|
stopMemoryMonitoring() // 先停止之前的监控
|
||||||
|
|
||||||
|
// 每30秒检查一次内存使用情况
|
||||||
|
memoryCheckTimer = Timer.scheduledTimer(withTimeInterval: 30.0, repeats: true) { [weak self] _ in
|
||||||
|
self?.checkMemoryPressure()
|
||||||
|
}
|
||||||
|
|
||||||
|
print("📊 内存监控已启动")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 停止内存监控
|
||||||
|
func stopMemoryMonitoring() {
|
||||||
|
memoryCheckTimer?.invalidate()
|
||||||
|
memoryCheckTimer = nil
|
||||||
|
print("📊 内存监控已停止")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存警告处理
|
||||||
|
|
||||||
|
@objc private func handleMemoryWarning() {
|
||||||
|
memoryWarningCount += 1
|
||||||
|
print("🚨 收到内存警告 #\(memoryWarningCount)")
|
||||||
|
|
||||||
|
// 立即执行内存清理
|
||||||
|
performMemoryCleanup()
|
||||||
|
|
||||||
|
// 通知其他组件
|
||||||
|
NotificationCenter.default.post(name: .memoryWarning, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存统计
|
||||||
|
|
||||||
|
/// 获取内存统计信息
|
||||||
|
func getMemoryStatistics() -> MemoryStatistics {
|
||||||
|
let details = getMemoryUsageDetails()
|
||||||
|
|
||||||
|
return MemoryStatistics(
|
||||||
|
usedMB: details.usedMB,
|
||||||
|
totalMB: details.totalMB,
|
||||||
|
percentage: details.percentage,
|
||||||
|
warningCount: memoryWarningCount,
|
||||||
|
timestamp: Date()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 打印内存统计信息
|
||||||
|
func printMemoryStatistics() {
|
||||||
|
let stats = getMemoryStatistics()
|
||||||
|
print("📊 内存统计信息:")
|
||||||
|
print(" - 已使用: \(String(format: "%.1f MB", stats.usedMB))")
|
||||||
|
print(" - 总内存: \(String(format: "%.1f MB", stats.totalMB))")
|
||||||
|
print(" - 使用率: \(String(format: "%.1f%%", stats.percentage))")
|
||||||
|
print(" - 警告次数: \(stats.warningCount)")
|
||||||
|
print(" - 检查时间: \(stats.timestamp)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存统计结构
|
||||||
|
struct MemoryStatistics {
|
||||||
|
let usedMB: Double
|
||||||
|
let totalMB: Double
|
||||||
|
let percentage: Double
|
||||||
|
let warningCount: Int
|
||||||
|
let timestamp: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 通知名称扩展
|
||||||
|
extension Notification.Name {
|
||||||
|
static let memoryWarning = Notification.Name("memoryWarning")
|
||||||
|
static let memoryCleanup = Notification.Name("memoryCleanup")
|
||||||
|
static let memoryCleanupSuggestion = Notification.Name("memoryCleanupSuggestion")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 内存优化工具
|
||||||
|
extension MemoryMonitor {
|
||||||
|
|
||||||
|
/// 检查是否需要进行内存优化
|
||||||
|
func shouldOptimizeMemory() -> Bool {
|
||||||
|
let details = getMemoryUsageDetails()
|
||||||
|
return details.percentage > 70.0 || details.usedMB > 200.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取内存优化建议
|
||||||
|
func getMemoryOptimizationSuggestions() -> [String] {
|
||||||
|
var suggestions: [String] = []
|
||||||
|
let details = getMemoryUsageDetails()
|
||||||
|
|
||||||
|
if details.percentage > 80.0 {
|
||||||
|
suggestions.append("内存使用率过高,建议关闭其他应用")
|
||||||
|
}
|
||||||
|
|
||||||
|
if details.usedMB > 250.0 {
|
||||||
|
suggestions.append("内存使用量过大,建议重启应用")
|
||||||
|
}
|
||||||
|
|
||||||
|
if memoryWarningCount > 3 {
|
||||||
|
suggestions.append("频繁收到内存警告,建议检查内存泄漏")
|
||||||
|
}
|
||||||
|
|
||||||
|
if suggestions.isEmpty {
|
||||||
|
suggestions.append("内存使用正常")
|
||||||
|
}
|
||||||
|
|
||||||
|
return suggestions
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 执行深度内存清理
|
||||||
|
func performDeepMemoryCleanup() {
|
||||||
|
print("🧹 执行深度内存清理")
|
||||||
|
|
||||||
|
// 1. 清理所有缓存
|
||||||
|
ImageCacheManager.shared.clearCache()
|
||||||
|
|
||||||
|
// 2. 清理临时文件
|
||||||
|
cleanupTempFiles()
|
||||||
|
|
||||||
|
// 3. 清理系统缓存
|
||||||
|
URLCache.shared.removeAllCachedResponses()
|
||||||
|
|
||||||
|
// 4. 通知所有组件进行清理
|
||||||
|
NotificationCenter.default.post(name: .deepMemoryCleanup, object: nil)
|
||||||
|
|
||||||
|
// 5. 强制垃圾回收
|
||||||
|
autoreleasepool {
|
||||||
|
// 执行内存密集型操作
|
||||||
|
let _ = Array(0..<1000).map { _ in String(repeating: "x", count: 1000) }
|
||||||
|
}
|
||||||
|
|
||||||
|
print("✅ 深度内存清理完成")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 深度清理通知
|
||||||
|
extension Notification.Name {
|
||||||
|
static let deepMemoryCleanup = Notification.Name("deepMemoryCleanup")
|
||||||
|
}
|
Loading…
Reference in new issue