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

不创建新实例调用ViewController及通知重复执行问题

Hey there! Let's break down your problem step by step—you've got two main issues here: a retain cycle causing your hello() function to fire twice via notifications, and needing to call hello() when the app becomes active without running into those duplicates. Here's how to fix both:

1. Fix the Retain Cycle First (Root Cause of Duplicate Calls)

The core issue is that MainViewController holds a strong reference to MainTabBarController, while the tab bar controller already strongly references its child view controllers (including MainViewController) via its viewControllers array. This creates a retain cycle—neither controller can be deallocated properly, so if you register a notification in MainTabBarController, the old instance's listener sticks around when you navigate back/forth, leading to duplicate calls.

Fix this by making the reference in MainViewController weak:

class MainViewController: UIViewController {
    // Use weak to avoid strong reference to the parent tab bar controller
    weak var mainTabBarController: MainTabBarController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Safely cast the parent tab bar controller instead of holding a strong reference
        self.mainTabBarController = self.tabBarController as? MainTabBarController
    }
}

Now the tab bar controller can deallocate normally when it's no longer needed, and its notification listeners will be cleaned up.

2. Properly Manage Notification Registration/Removal

Even with the retain cycle fixed, you need to ensure notifications are only registered once and removed when the controller is gone. Here's the clean way to handle this in MainTabBarController:

class MainTabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Register your custom notification
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(hello),
            name: NSNotification.Name("YourCustomNotification"), // Replace with your actual notification name
            object: nil
        )
    }
    
    deinit {
        // Remove ALL observers for this instance when it's deallocated
        NotificationCenter.default.removeObserver(self)
    }
    
    @objc func hello() {
        print("Hello called!")
        // Your existing logic here
    }
}

The deinit method will now run thanks to the fixed retain cycle, ensuring no leftover notification listeners cause duplicate calls.

3. Call hello() When the App Becomes Active (Without Duplicates)

Instead of using a notification to trigger hello() from AppDelegate/SceneDelegate (which could overlap with your existing notification), directly call the method on the active MainTabBarController instance:

For iOS 12 and below (AppDelegate):

class AppDelegate: UIResponder, UIApplicationDelegate {
    func applicationDidBecomeActive(_ application: UIApplication) {
        // Grab the root tab bar controller safely
        guard let mainTabBarController = UIApplication.shared.keyWindow?.rootViewController as? MainTabBarController else {
            return
        }
        mainTabBarController.hello()
    }
}

For iOS 13+ (SceneDelegate):

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func sceneDidBecomeActive(_ scene: UIScene) {
        guard let window = window,
              let mainTabBarController = window.rootViewController as? MainTabBarController else {
            return
        }
        mainTabBarController.hello()
    }
}

This way, you're directly invoking the method without relying on notifications, so no risk of duplicate calls from overlapping event triggers.

Quick Recap

  • Break the retain cycle with a weak reference in MainViewController
  • Clean up notifications in deinit to avoid leftover listeners
  • Directly call hello() from AppDelegate/SceneDelegate instead of using notifications for that trigger

内容的提问来源于stack exchange,提问作者Kárpáti András

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:17:49