You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS Swift项目中如何全局共享选中的Patient对象?

Solution for Sharing a Single Patient Object Across View Controllers in macOS (Swift 3.2 / Xcode 8.3)

Hey there! Let's tackle this global patient sharing problem for your macOS app. You’ve tried notifications, delegates, and segues without luck—so let’s look at two clean, straightforward approaches that fit your setup perfectly:


1. Singleton Pattern (Quickest Implementation)

Since you already have a ChosenPatient class, turning it into a singleton is the simplest way to ensure a single, globally accessible instance. This lets any view controller access the selected patient directly.

Step 1: Update the ChosenPatient Class

Modify your existing class to include a static shared instance, and add an optional notification trigger when the patient data changes:

class ChosenPatient: NSObject {
    // Global singleton instance—only one exists across the app
    static let shared = ChosenPatient()
    
    var data = Patient() {
        didSet {
            // Optional: Notify other VCs when the patient is updated
            NotificationCenter.default.post(
                name: NSNotification.Name(rawValue: "ChosenPatientDidUpdate"),
                object: nil
            )
        }
    }
    
    // Keep your existing methods here
    // ... your existing methods ...
}

Step 2: Use the Singleton in SearchViewController

When a user selects a patient in your table view, update the singleton’s data:

// Inside your SearchViewController's table view selection handler
func tableView(_ tableView: NSTableView, didSelectRowAt row: Int) {
    let selectedPatient = // Get your selected Patient object from Realm/data source
    ChosenPatient.shared.data = selectedPatient
    // Call updateLabels if needed for this VC
    updateLabels()
}

Step 3: Access the Patient in DetailViewController

In your DetailViewController’s updateLabels() method, directly fetch the singleton’s data. If you want to auto-update when the patient changes, add a notification observer:

override func viewDidLoad() {
    super.viewDidLoad()
    // Listen for patient updates to refresh labels automatically
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(updateLabels),
        name: NSNotification.Name(rawValue: "ChosenPatientDidUpdate"),
        object: nil
    )
}

@objc func updateLabels() {
    let currentPatient = ChosenPatient.shared.data
    // Update your labels here, e.g.:
    nameLabel.stringValue = currentPatient.name
    // ... other label updates ...
}

// Clean up the observer when the VC is deallocated
deinit {
    NotificationCenter.default.removeObserver(self)
}

2. Dependency Injection (More Flexible & Testable)

If you prefer a more decoupled approach (great for long-term maintainability), use your root TabViewController to hold the ChosenPatient instance and pass it to both child view controllers.

Step 1: Add a Property to TabViewController

class TabViewController: NSTabViewController {
    // Hold the single ChosenPatient instance
    let sharedChosenPatient = ChosenPatient()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Pass the instance to both child VCs when the tab view loads
        passSharedPatientToChildren()
    }
    
    private func passSharedPatientToChildren() {
        if let searchVC = viewControllers?[0] as? SearchViewController {
            searchVC.chosenPatient = sharedChosenPatient
        }
        if let detailVC = viewControllers?[1] as? DetailViewController {
            detailVC.chosenPatient = sharedChosenPatient
        }
    }
}

Step 2: Add a Property to Child View Controllers

In both SearchViewController and DetailViewController, add a reference to ChosenPatient:

// In SearchViewController
class SearchViewController: NSViewController {
    var chosenPatient: ChosenPatient!
    
    // When selecting a patient:
    func tableView(_ tableView: NSTableView, didSelectRowAt row: Int) {
        let selectedPatient = // Get selected Patient
        chosenPatient.data = selectedPatient
        updateLabels()
    }
}

// In DetailViewController
class DetailViewController: NSViewController {
    var chosenPatient: ChosenPatient!
    
    @objc func updateLabels() {
        let currentPatient = chosenPatient.data
        // Update labels here
    }
}

Which Approach Should You Choose?

  • Singleton: Go with this if you want the fastest, simplest implementation. It’s perfect for small to medium apps where you don’t anticipate needing multiple "selected patient" instances.
  • Dependency Injection: Choose this if you want more control, easier testing, or plan to expand your app’s architecture later. It keeps your code loosely coupled and avoids the "global state" pitfalls of singletons.

Both approaches will let you access the same Patient object across any view controller in your app—pick the one that best fits your workflow!

内容的提问来源于stack exchange,提问作者AlbertUI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:28:48