ApplicationDidBecomeActive - “Bir görünüm denetleyicisi uygulamanın etkin hale gelmesine nasıl yanıt verebilir?”


179

UIApplicationDelegateAna AppDelegate.m sınıfımda applicationDidBecomeActivetanımlanan yöntemle protokol var .

Uygulama arka plandan döndüğünde bir yöntem çağırmak istiyorum, ancak yöntem başka bir görünüm denetleyicisinde. Şu anda applicationDidBecomeActiveyöntemde hangi görünüm denetleyicisinin gösterildiğini nasıl kontrol edebilirim ve ardından bu denetleyicideki bir yöntemi nasıl arayabilirim?

Yanıtlar:


304

Uygulamanızdaki herhangi bir sınıf, uygulamadaki farklı bildirimler için bir "gözlemci" olabilir. Görünüm denetleyicinizi oluşturduğunuzda (veya yüklediğinizde), denetleyiciyi gözlemci olarak kaydetmek UIApplicationDidBecomeActiveNotificationve bu bildirim uygulamanıza gönderildiğinde aramak istediğiniz yöntemi belirtmek isteyeceksiniz.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(someMethod:)
                                             name:UIApplicationDidBecomeActiveNotification object:nil];

Kendinizi temizlemeyi unutmayın! Görüşünüz kaybolurken kendinizi gözlemci olarak çıkarmayı unutmayın:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification
                                              object:nil];

Bildirim Merkezi hakkında daha fazla bilgi .


Mükemmel. Kullanmayı düşünmedim NSNotificationCenter. Teşekkür ederim!
Calvin

3
Bu kod satırındaki bir yazım hatası (eksik 'ad'): [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (someMethod :) name: UIApplicationDidBecomeActiveNotification nesnesi: nil];
Johnus

3
Reed'in cevabına eklemek için, çağrılan yöntemin (bu örnekte someMethod) bir NSNotification parametresini kabul etmesi gerekir. SomeMethod için yöntem imzası, - (void) someMethod: (NSNotification *) bildirimi {// Burada Bir Şey Yapın}
Aaron

2
@Aaron Olabilir, ancak bu bir gereklilik değildir. Yine de bu büyük bir içgörü. Teşekkürler!
Reed Olsen

Fantastik! Bir kişinin sahip olduğu NSTimer örneklerini geçersiz kılmak / yeniden oluşturmak için, bu NSTimerlerden sorumlu olan görünüm denetleyicileri / diğer nesneler için ne harika bir yol. Sevdim!
idStar

68

Swift 3, 4 Eşdeğeri:

gözlemci eklemek

NotificationCenter.default.addObserver(self,
    selector: #selector(applicationDidBecomeActive),
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

gözlemciyi kaldırmak

NotificationCenter.default.removeObserver(self,
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

geri aramak

@objc func applicationDidBecomeActive() {
    // handle event
}

2
bunu nereye çağırırım?

1
@ user8169082'de bildirim almaya başlamanız gereken her yere bir gözlemci eklersiniz. Örneğin viewDidLoadveya üzerine ekleyebilirsiniz viewWillAppear:animated. Artık bildirime ihtiyacınız olmadığında veya gözlemci örneğiniz deinit yönteminde yeniden konumlandırılacaksa bir gözlemciyi kaldırabilirsiniz
igrek

2
swift 4.2 Kullanıyorum: NotificationCenter.default.addObserver (self, selector: #selector (applicationDidBecomeActive (bildirim :)), isim: UIApplication.didBecomeActiveNotification, nesne: nil)
Brian

16

Swift 2 Eşdeğeri :

let notificationCenter = NSNotificationCenter.defaultCenter()

// Add observer:
notificationCenter.addObserver(self,
  selector:Selector("applicationWillResignActiveNotification"),
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove observer:
notificationCenter.removeObserver(self,
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove all observer for all notifications:
notificationCenter.removeObserver(self)

// Callback:
func applicationWillResignActiveNotification() {
  // Handle application will resign notification event.
}

removeObserverSwift: deinityöntem koymak için en iyi yer .
Enrico Susatyo

Genel olarak, kendi kendine deinit içinde erişilmesi önerilmez; bu noktada, benlik tamamen tahsis edilmek ve
yerle bir etmek

1
O zaman Server'ı nereden kaldırırsınız?
Enrico Susatyo

2
@EnricoSusatyo doğru olmadığı için bunu göz ardı edebilirsiniz. Deinit'i geçersiz kılmak iyidir: "Bir örnek, deinitializer'ı çağrılıncaya kadar yeniden konumlandırılmadığından, deinitializer, çağrıldığı örneğin tüm özelliklerine erişebilir ve davranışını bu özelliklere (ör. kapatılması gereken dosya). " Deinit aramak iyi değil
Dan Rosenstark

7

Hızlı 4.2

Gözlemci ekle-

NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: UIApplication.didBecomeActiveNotification, object: nil)

Gözlemciyi kaldır-

NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)

İşlem Etkinliği

@objc func handleEvent() {
}

5

Swift 4 ile Apple, yeni bir derleyici uyarısı yoluyla #selectorbu senaryoda kullanılmasını önlediğimizi bildiriyor. Aşağıdakiler bunu başarmanın çok daha güvenli bir yoludur:

İlk olarak, bildirim tarafından kullanılabilecek tembel bir değişken oluşturun:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in
    // Do stuff
} 

Gerçek bildirimin dahil edilmesini istiyorsanız, _ile değiştirin notification.

Ardından, uygulamanın etkinleştiğini gözlemlemek için bildirim ayarladık.

func setupObserver() {
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive,
                                               object: nil,
                                               queue:.main,
                                               using: didBecomeActive)
}

Buradaki büyük değişiklik, a'yı çağırmak yerine, #selectorşimdi yukarıda oluşturulan varlığı çağırıyoruz . Bu, geçersiz seçici çökmeleri olan durumları ortadan kaldırabilir.

Sonunda gözlemciyi kaldırıyoruz.

func removeObserver() {
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil)
}

1
#selector@objcSwift 4'te öznitelik olarak bildirilen bir yöntemi çağırabilir
AnBisw

1
kullanmak yanlıştır removeObserver(selfçünkü gözlemci eklenirken kendiliğinden atanmamıştır. You should let observer = NotificationCenter.default.addObserversonraremoveObserver(observer
Yan Kalbaska

Teşekkürler @CodeBender Bu işlevi henüz bilmiyordum ve (sonunda) kaldırır @objc. Ancak denediğimde konsolda bir uyarı alıyorum (Xcode 11.3.1 (11C504), Swift 13.3): BackgroundTask sona erdirilemiyor : Tanımlayıcıda arka plan görevi yok. Gözlemciyi NSObjectProtocol olarak bir değişkene kaydetsem bile.
palme

Boşver @objcVaryantı kullanırsam uyarıyı da alırım .
palme

3

Hızlı 5

fileprivate  func addObservers() {
      NotificationCenter.default.addObserver(self,
                                             selector: #selector(applicationDidBecomeActive),
                                             name: UIApplication.didBecomeActiveNotification,
                                             object: nil)
    }

fileprivate  func removeObservers() {
        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }

@objc fileprivate func applicationDidBecomeActive() {
// here do your work
    }

0

Birleştirmek yolu:

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.