2012-04-25 3 views
25

У меня есть несколько приложений для iOS, которые используют один и тот же порт для прослушивания сетевого маяка. На основном представлении я использую viewWillDisappear, чтобы закрыть порт, когда открывается другой вид, который отлично работает. Затем я заметил, что если бы я нажал кнопку «домой» с главного контроллера представления, не открывая другой вид, чтобы закрыть порт, тогда порт остается открытым, а другие мои приложения не могут прослушивать этот порт. Затем я попытался использовать viewWillUnload, но это, похоже, не вызвано, когда я нажимаю кнопку «домой».Обнаружение при нажатии кнопки дома iOS

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

View will unload никогда не отображается в консоли, что заставляет меня полагать, что метод никогда не будет вызван.

Есть ли способ обнаружить, когда нажата кнопка дома, чтобы закрыть порт?

+3

Попробуйте использовать метод «applicationWillTerminate» ,:-) –

+1

Метод "applicationWillTerminate" не существует. Однако подклассы могут регистрироваться для UIApplicationWillTerminateNotification, а затем выполнять свою собственную очистку или закрывать. –

ответ

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

+2

У меня был код, чтобы закрыть порт в viewWillDisappear, и он, похоже, не получил вызов. Порт останется открытым, и все остальные приложения, которые использовали порт, потерпят неудачу. Я установил метод класса, чтобы закрыть порт и вызвать его из applicationDidEnterBackground, и он отлично работает – nick

+7

'viewWillDisappear' или' viewDidDisappear' не вызывается при нажатии кнопки «Домой» или прекращается приложение. Лучшее решение - использовать уведомление 'UIApplicationWillResignActiveNotification' – Sam

5

viewWillUnload часто не называют, кроме как в случае нехватки памяти. Вам лучше реализовать application delegate methodsapplicationDidEnterBackground: или applicationWillTerminate: и выполнить там работу или отправить уведомление части вашего приложения, которая знает, как обрабатывать процесс очистки.

5

viewWillUnload обычно не вызывается, за исключением случаев с низкой памятью. Использование этих вместо:

В вашем App Делегат:

- (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:. 
} 

Или, если вы хотите использовать код в View Controller:

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

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

viewWill/DidDisappear вызывается, когда приложение закрывается. Не когда кнопка «Домой» нажата, чтобы минимизировать приложения для центра управления. – khunshan

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

+1

Я отредактировал код для использования nil. – PeterPurple

+8

На самом деле уведомление 'applicationWillResignActive' - это не всегда лучший способ сделать это, так как функция resign active также включает (случайное) слайд вниз меню или новое слайд-меню внизу в ios 7.' applicationDidEnterBackground' означает, что ваше приложение было «сведено к минимуму», , и доступен с iOS 4. – bobobobo

10

В случае Swift пользователя

вы можете написать его как этот

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 –

2

Лучше использовать UIApplicationWillResignActive и UIApplicationDidBecomeActive из-за того, что они улавливают «захват и освобождение верхнего прямоугольника». Я хотел бы предложить использовать этот корневой класс:

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() 
    } 

} 

Override onStop() и onStart() внутри Чайлдс, чтобы поймать всех вид появления/исчезновения

То есть,

class SomeViewController: VBase { 

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