2012-04-25 185 views
25

我有幾個iOS應用程序都使用相同的端口來偵聽網絡信標。在主視圖中,我使用viewWillDisappear在另一個視圖打開時關閉端口,這非常有效。然後我注意到,如果我從主視圖控制器按下主頁按鈕而沒有打開另一個視圖關閉端口,那麼端口保持打開狀態,而我的其他應用程序不能再監聽該端口。然後我嘗試使用viewWillUnload,但是當我按下主頁按鈕時似乎沒有被調用。按下主頁按鈕時檢測iOS

-(void)viewWillUnload 
{ 
    //[super viewWillUnload]; 
    NSLog(@"View will unload"); 
    [udpSocket close]; 
    udpSocket = nil; 
} 

查看將卸載永遠不會顯示在控制檯,這導致我相信該方法永遠不會被調用。

有沒有辦法檢測何時按下主頁按鈕,所以我可以關閉我的端口?

+3

嘗試使用「applicationWillTerminate」方法。:-) – 2012-04-25 22:35:09

+1

「applicationWillTerminate」方法不存在。但是,子類可以註冊UIApplicationWillTerminateNotification,然後執行自己的清理或關閉。 – 2012-05-18 15:02:47

回答

39

這是你的選擇

在你的應用程序代理:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
} 

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
} 
+0

因爲我明顯同意,+1 – DGund 2012-04-26 00:40:02

+2

我有代碼關閉在viewWillDisappear中的端口,它似乎並沒有被調用。端口將保持打開狀態,所有其他使用此端口的應用程序都會失敗。我設置了一個類方法來關閉端口並從applicationDidEnterBackground調用它,並且它工作的很好 – nick 2012-04-26 04:19:16

+7

當按下Home按鈕或應用程序終止時,viewWillDisappear或viewDidDisappear不會被調用。最好的解決方案是使用'UIApplicationWillResignActiveNotification'通知 – Sam 2013-10-07 10:42:09

5

viewWillUnload通常不叫除了在內存不足的情況。你最好實施application delegate methodsapplicationDidEnterBackground:applicationWillTerminate:,並在那裏完成工作,或向您的應用程序的知道如何處理清理過程的部分發送通知。

5

viewWillUnload通常不會調用,除非內存不足。用這些來代替:

在應用程序委託:

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
} 

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
} 

或者,如果你想在你的瀏覽器使用代碼:

- (void)viewDidDisappear:(BOOL)animated 
{ 
//Put code here 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
//Put code here 
} 
+0

viewWill/DidDisappear將在應用程序關閉時調用。當Home Button按下時,不會將應用程序最小化到控制中心。 – khunshan 2014-08-06 11:14:30

31

處理最簡單的方法就是註冊在視圖控制器中收到UIApplicationWillResignActiveNotification通知。

該事件在家裏按下按鈕,鎖在一個電話

- (void) applicationWillResign{ 
    NSLog(@"About to lose focus"); 
} 

- (void) myVcInitMethod { 
    [[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(applicationWillResign) 
     name:UIApplicationWillResignActiveNotification 
     object:nil]; 
} 
+3

爲什麼要傳遞NULL而不是nil? – mszaro 2013-08-16 18:04:51

+1

我編輯了代碼以使用nil。 – PeterPurple 2013-11-29 17:58:12

+8

實際上'applicationWillResignActive'通知並不總是這樣做的最好方式,因爲resign active還包括(意外)向下滑動頂層菜單,或者在ios 7中新增底部菜單。'applicationDidEnterBackground'意味着您的應用程序被「最小化」 ,並可從iOS 4獲得。 – bobobobo 2014-01-01 18:26:28

10

在雨燕用戶的情況下發出

,你可以把它寫這樣

override func viewDidLoad() { 
    super.viewDidLoad() 

    // code here... 

    NSNotificationCenter.defaultCenter().addObserver(
     self, 
     selector: "applicationWillResignActive:", 
     name: UIApplicationWillResignActiveNotification, 
     object: nil) 
} 

func applicationWillResignActive(notification: NSNotification) { 
    print("I'm out of focus!") 
} 

也,當你的應用程序終止時,別忘了關閉它

deinit { 

    // code here... 

    NSNotificationCenter.defaultCenter().removeObserver(self) 
} 
+0

如果你使用的是iOS 9或更高版本,你可以忘記在deinit方法中刪除觀察者。但是,只有當你不打算支持iOS 8或更早版本。 而且,如@ bobobobo所說,您應該使用applicationDidEnterBackground – 2017-10-20 13:20:18

2

更好的使用UIApplicationWillResignActiveUIApplicationDidBecomeActive,因爲它們捕獲了「頂部矩形捕獲和釋放事件」。 我會建議使用這根類:

class VBase: UIViewController { 
    fileprivate var listenersActivated = false 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view. 
    } 
    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     onStart() 
    } 
    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 
     onStop() 
     removeListeners() 
    } 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
     onStop() 
     removeListeners() 
    } 

    internal func iniListeners() { 
     if (!listenersActivated) { 
      NotificationCenter.default.addObserver(self, selector: #selector(onStop), name: NSNotification.Name.UIApplicationWillResignActive, object: nil) 
      NotificationCenter.default.addObserver(self, selector: #selector(onStart), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil) 
      listenersActivated = true 
     } else { 

     } 
    } 
    internal func removeListeners() { 
     NotificationCenter.default.removeObserver(self) 
     listenersActivated = false 
    } 
    internal func onStop() { 

    } 
    internal func onStart() { 
     iniListeners() 
    } 

} 

覆蓋onStop()onStart()裏面孩子的捕獲所有視圖出現/消失

也就是說,

class SomeViewController: VBase { 

... 
    override func onStart() { 
     super.onStart() 
     someFunctionToInitialize() 
    } 
    override func onStop() { 
     super.onStop() 
     stopTimer() 
     someFunctionToDesctruction() 
    } 
}