NotificationCenter — özü, çalışma prensibi ve bildirim mimarisi

Yazar: IT Sectr Yayınlanma: 2026-03-18 Okuma süresi: 10 dk

NotificationCenter, gönderen ve alıcı arasında doğrudan bağlantı olmadan uygulama bileşenleri arasında bildirim göndermek ve almak için iOS'ta bir sistem mekanizmasıdır. Observer desenine dayanan NotificationCenter, nesnelerin olaylara abone olmasına ve bunlara asenkron olarak yanıt vermesine olanak tanır. Apple Documentation'a (2025) göre NSNotificationCenter, post(name:object:) aracılığıyla senkron bildirim göndermeyi ve NotificationQueue aracılığıyla gecikmeli göndermeyi destekler. Bildirim merkezi tek bir işlem içinde çalışır ve uygulama sınırlarını aşmaz.

Kilit Noktalar

  • NotificationCenter — iOS bileşenleri arasında olay alışverişi için Observer deseninin bir uygulaması.
  • addObserver, bir nesneyi belirli bir ad ve gönderen nesneyle bildirimlere abone yapar.
  • post(name:object:), abone olan tüm gözlemcilere senkron olarak bir bildirim gönderir.
  • removeObserver deinit içinde çağrılmalıdır, aksi takdirde bildirim gönderilirken çökme meydana gelir.
  • NotificationQueue, asenkron teslimat için bildirimleri ertelemeye olanak tanır.

NotificationCenter Nedir?

NotificationCenter (NSNotificationCenter), nesneler arasında gevşek bağlı iletişim uygulamak için yerleşik bir iOS mekanizmasıdır. Observer deseni, bir nesnenin (gönderen), doğrudan bir referans olmadan birden çok diğer nesneye (gözlemci) bir olay hakkında bildirimde bulunmasına olanak tanır. NotificationCenter üç varlıkla çalışır: Notification.Name (bildirim tanımlayıcı), Notification (veri içeren kap) ve NotificationCenter (dağıtıcı). Her uygulamanın paylaşılan bir default center'ı vardır.

NSNotification ve Notification.Name

Notification.Name, bildirim türünü tanımlayan bir yapıdır. extension Name: Notification.Name(“MyNotification”) ile oluşturulur. Notification, name, object (gönderen) ve userInfo (veri içeren sözlük) içeren bir nesnedir. Sistem bildirimleri sabit olarak bildirilir: UIApplication.didBecomeActiveNotification, UIResponder.keyboardWillShowNotification. Özel bildirimler, ad çakışmalarını önlemek için extension aracılığıyla gruplandırılmalıdır. İsimler ters alan adı biçiminde olmalıdır.

swift
// Özel bildirimler tanımlama
extension Notification.Name {
    static let dataDidUpdate =
        Notification.Name("com.app.dataDidUpdate")
    static let userLoggedOut =
        Notification.Name("com.app.userLoggedOut")
}

// Veriyle bildirim gönderme
let userInfo: [String: Any] = [
    "userId": 123,
    "timestamp": Date()
]
NotificationCenter.default.post(
    name: .dataDidUpdate,
    object: nil,
    userInfo: userInfo
)

Gözlemci Ekleme (addObserver)

Gözlemci, addObserver(_:selector:name:object:) yöntemi aracılığıyla bir bildirime abone olur. Selector, bildirim alındığında çağrılacak yöntemdir. object parametresi, belirli bir gönderenden gelen bildirimleri filtrelemeye olanak tanır. object nil ise, gözlemci herhangi bir gönderenden belirtilen ada sahip tüm bildirimleri alır. iOS 9'dan itibaren addObserver, block-based API için manuel kaldırma gerektirmez, ancak selector-based hala removeObserver gerektirir.

swift
// Bir bildirime abone olma (selector tabanlı)
NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleDataUpdate),
    name: .dataDidUpdate,
    object: nil
)

@objc func handleDataUpdate(_ notification: Notification) {
    guard let userId = notification.userInfo?["userId"] as? Int else { return }
    updateUI(for: userId)
}

// Bir bildirime abone olma (block tabanlı, iOS 9+)
var observer: NSObjectProtocol?
observer = NotificationCenter.default.addObserver(
    forName: .dataDidUpdate,
    object: nil,
    queue: .main
) { [weak self] notification in
    guard let self else { return }
    self.handleNotification(notification)
}

NotificationCenter Nasıl Çalışır?

NotificationCenter bir eşleme tablosu (ad → gözlemci kümesi) saklar. Gönderen post(name:object:) çağırdığında, bildirim merkezi senkron olarak bu ada abone olan tüm gözlemcileri dolaşır ve seçicilerini veya bloklarını çağırır. Kilit özellik: post, tüm işleyiciler tamamlanana kadar geçerli iş parçacığını bloklar. İşleyiciler ağır işlemler yaparsa, bu göndereni geciktirir. NotificationQueue, bildirim teslimatını erteleyerek bu sorunu çözer.

Senkron Gönderme (post)

post(name:object:userInfo:) yöntemi, tüm gözlemcilere hemen bir bildirim gönderir. Çağrı senkronizedir — post'tan sonraki kod, yalnızca tüm işleyiciler tamamlandıktan sonra yürütülür. Gözlemcilerin çağrılma sırası garanti edilmez ve çalıştırmalar arasında değişebilir. Sıralı işleme için coalescing ile NotificationQueue kullanın. Aynı bildirimin işleyicisi içinde post çağırmayın — bu sonsuz özyinelemeye yol açar.

Gecikmeli Gönderme (NotificationQueue)

NotificationQueue, asenkron teslimat için bildirimleri bir kuyruğa ekler. Coalescing (aynı bildirimleri birleştirme) ve teslimat kuyruğu seçimini (asap, idle, modal) destekler. Coalescing, yalnızca son değerle bildirimde bulunmanız gereken sık olaylar (indirme ilerlemesi) için kullanışlıdır. NotificationQueue, ateşlemek için run loop kullanır, bu nedenle yalnızca etkin run loop'a sahip iş parçacıklarında çalışır.

swift
// NotificationQueue ile gecikmeli gönderme
let notification = Notification(
    name: .dataDidUpdate,
    object: self,
    userInfo: ["progress": 0.5]
)

// Coalescing: birden çok bildirim birleştirilir
NotificationQueue.default.enqueue(
    notification,
    postingStyle: .whenIdle,
    coalesceMask: .onName,
    forModes: [.common]
)

// DispatchQueue ile asenkron teslimat
DispatchQueue.main.async {
    NotificationCenter.default.post(name: .dataDidUpdate, object: nil)
}

Notification vs Delegate vs KVO

iOS, nesneler arasında iletişim için üç ana mekanizma sağlar: NotificationCenter, Delegate ve KVO (Key-Value Observing). Her biri bildirim sorununu çözer ancak bağlantı, performans ve tür güvenliği konularında farklı ödünleşimlerle birlikte gelir. Mekanizma seçimi, bire-bir veya bire-çok ilişkisine ve veri aktarımı ihtiyacına bağlıdır.

ÖzellikNotificationCenterDelegateKVO
BağlantıZayıf (bildirim adı)Güçlü (protokol)Orta (anahtar)
İlişkiBire-çokBire-birBire-çok
Tür güvenliğiDüşük (userInfo Dictionary olarak)Yüksek (protokol yöntemleri)Orta (Any?)
PerformansOrta (tablo dolaşımı)Yüksek (doğrudan çağrı)Düşük (NSObject)
EşzamansızlıkSenkron (post bloklar)Gönderenin iş parçacığında senkronDeğişiklikte senkron

NotificationCenter Ne Zaman Seçilmeli

NotificationCenter, birden çok bağımsız bileşenin yanıt vermesi gereken olaylar için idealdir. Örnekler: uygulama ayarları değişiklikleri, kullanıcı çıkışı, arka planda push bildirimi alma. NotificationCenter ayrıca gevşek bağlı modüller için de uygundur (A özelliği B özelliğini bilmemelidir). Dezavantajı, tür güvenliği eksikliğidir: userInfo anahtarları enum değil, dizelerdir.

Delegate veya KVO Ne Zaman Seçilmeli

Delegate, net bir sözleşmeye (tableView.delegate) sahip bire-bir ilişkiler için tercihtir. Delegate daha hızlı ve türler açısından daha güvenlidir. KVO, modelin belirli bir özelliğindeki (isLoading, progress) değişiklikleri gözlemlemek için tercihtir. KVO, NSObject'ten kalıtım gerektirir ve hata ayıklamada zorluklara neden olabilir (sihirli dize anahtarları). Modern Swift'te, Combine ve async dizileri her üç yaklaşımın da yerini alır.

AddObserver: Senkron ve Asenkron Bildirimler

addObserver yöntemi iki abonelik çeşidini destekler: selector-based (geleneksel) ve block-based (closure ile). Selector-based, @objc uyumluluğu ve manuel gözlemci kaldırma gerektirir. Block-based (iOS 9+), bir capture list kullanımına izin verir ve güçlü referanslar olmadan bloklar kullanıldığında işletim sistemi tarafından otomatik olarak yönetilir. Block-based ayrıca queue'yu da destekler — gözlemci, belirtilen kuyrukta bildirimi alır.

Selector tabanlı addObserver

Selector aracılığıyla geleneksel abonelik yöntemi. İşleyici yöntemi @objc ile işaretlenmeli ve isteğe bağlı bir Notification kabul etmelidir. Avantajı: eski Objective-C dahil herhangi bir sınıf tarafından kullanılabilir. Dezavantajları: seçicinin tür güvenliği eksikliği, seçici adında yazım hatası riski, deinit'te zorunlu removeObserver. Gözlemci nesneden önce kaldırılırsa, işleyici çağrılmaz.

Block tabanlı addObserver

Block-based API, bildirim alındığında yürütülen bir closure kabul eder. queue parametresi, bloğun hangi kuyrukta çalıştırılacağını belirler — UI güncellemeleri için ana kuyruk veya veri işleme için arka plan kuyruğu. Dönüş değeri NSObjectProtocol, gözlemciyi kaldırmak için kullanılır: NotificationCenter.default.removeObserver(observer). Modern Swift'te block-based tercih edilir.

swift
protocol NotificationToken {
    func dispose()
}

extension NotificationCenter {
    func observe(
        name: NSNotification.Name,
        object: Any? = nil,
        queue: OperationQueue? = .main,
        using block: @escaping (Notification) -> Void
    ) -> NotificationToken {
        let observer = addObserver(forName: name, object: object,
                                   queue: queue, using: block)
        return NotificationTokenWrapper(observer: observer, center: self)
    }
}

// Otomatik kaldırma ile kullanma
class ViewModel {
    private var tokens: [NotificationToken] = []

    func startObserving() {
        let token = NotificationCenter.default.observe(
            name: .dataDidUpdate,
            queue: .main
        ) { [weak self] notification in
            self?.handleUpdate(notification)
        }
        tokens.append(token)
    }

    deinit {
        tokens.forEach { $0.dispose() }
    }
}

Bellek Yönetimi ve Gözlemcileri Kaldırma

Bellek sızıntıları, NotificationCenter ile çalışırken ana sorunlardan biridir. Bir gözlemci, ayrılmadan önce kaldırılmazsa, bildirim gönderilirken merkez, zaten ayrılmış bir nesnede bir yöntem çağırmaya çalışarak EXC_BAD_ACCESS'e neden olur. iOS 9'dan itibaren block-based addObserver zayıf referanslar kullanır, ancak selector-based hala manuel removeObserver gerektirir. En iyi uygulama: gözlemciyi deinit içinde kaldırın.

removeObserver Ne Zaman Çağrılmalı

Selector-based: deinit içinde her zaman NotificationCenter.default.removeObserver(self) çağrısı yapın. Gözlemci birden çok bildirime abone ise, hepsini bir kerede (parametresiz) veya ada göre belirli birini kaldırabilirsiniz. Block-based: addObserver'dan döndürülen token ile removeObserver aracılığıyla kaldırın. iOS 9+ üzerinde block-based için sızıntı olmaz, ancak performans için kaldırma yine de önerilir: ayrılmış gözlemciler post sırasında dolaşılmaz.

swift
class SafeObserver {
    private var observers: [NSObjectProtocol] = []

    func addSubscriptions() {
        let token1 = NotificationCenter.default.addObserver(
            forName: .dataDidUpdate, object: nil,
            queue: .main) { [weak self] _ in
            self?.refreshData()
        }
        let token2 = NotificationCenter.default.addObserver(
            forName: .userLoggedOut, object: nil,
            queue: .main) { [weak self] _ in
            self?.logout()
        }
        observers.append(contentsOf: [token1, token2])
    }

    deinit {
        observers.forEach { NotificationCenter.default.removeObserver($0) }
    }

    private func refreshData() { }
    private func logout() { }
}

Token Deseni ile Zayıf Referanslar

Token deseni, gözlemci yönetimini otomatikleştirir. Abonelikte, ayrılma sırasında otomatik olarak gözlemciyi kaldıran bir token nesnesi (NSObjectProtocol) döndürülür. NotificationTokenWrapper, NotificationCenter ve gözlemci token'ına zayıf bir referans saklar ve deinit içinde removeObserver'ı çağırır. Bu, NotificationCenter'ı AnyCancellable'ın abonelik yaşam döngüsünü yönettiği Combine yaklaşımına yaklaştırır.

Çoklu İş Parçacıklı Ortamda NotificationCenter

İş parçacığı güvenliği: NotificationCenter, post'un herhangi bir iş parçacığından çağrılabileceğini ve tüm gözlemcilerin bildirimi, post'un çağrıldığı aynı iş parçacığında alacağını garanti eder. Bu, çok iş parçacıklı uygulamalar için kritiktir: bir arka plan iş parçacığından bildirim gönderilirse, işleyiciler de arka plan iş parçacığında yürütülür. UI güncellemeleri için, DispatchQueue.main.async aracılığıyla işlemeyi ana kuyruğa gönderin.

post ve addObserver'ın İş Parçacığı Güvenliği

NotificationCenter, farklı iş parçacıklarından post ve addObserver çağrıları için iş parçacığı güvenlidir. Dahili senkronizasyon kilitleme kullanır, bu nedenle birden çok iş parçacığından sık post çağrıları çekişme yaratabilir. Yüksek yük senaryoları (1000 dosyanın indirme ilerlemesi) için ayrı bir bildirim kuyruğu veya Combine yayıncısı kullanın. postingStyle .now ile NotificationQueue, doğrudan post ile eşdeğerdir.

Combine ile Asenkron Teslimat

NotificationCenter, NotificationCenter.default.publisher(for:object:) aracılığıyla Combine yayıncısını destekler. Publisher, her bildirimi map, filter, debounce ve throttle ile dönüştürülebilen bir Combine olayına dönüştürür. Bu, senkron teslimat sorununu çözer: Combine, bildirimleri belirtilen Zamanlayıcıda asenkron olarak işler. NotificationCenter.publisher, eski mekanizma ile modern reaktif programlama arasında bir köprüdür.

swift
import Combine

class ReactiveViewModel {
    private var cancellables = Set<AnyCancellable>()

    func setupCombineSubscription() {
        NotificationCenter.default
            .publisher(for: .dataDidUpdate)
            .receive(on: DispatchQueue.main)
            .compactMap { $0.userInfo?["progress"] as? Float }
            .debounce(for: .seconds(0.3), scheduler: RunLoop.main)
            .sink { [weak self] progress in
                self?.progressLabel.text = "\(Int(progress * 100))%"
            }
            .store(in: &cancellables)
    }
}

Sıkça Sorulan Sorular

NotificationCenter iş parçacığı güvenli midir?

Evet, NotificationCenter herhangi bir iş parçacığından post ve addObserver çağrıları için iş parçacığı güvenlidir. Ancak işleyiciler, post'un çağrıldığı aynı iş parçacığında yürütülür. UI güncellemeleri için block-based addObserver'da queue: .main kullanın veya işleyici içinde DispatchQueue.main.async kullanın. receive(on:) ile Combine yayıncısı da iş parçacığı sorununu çözer.

Gözlemciyi kaldırmazsam ne olur?

Selector-based: gözlemcinin ayrılmasından sonra bildirim gönderirken EXC_BAD_ACCESS çökmesi. Block-based (iOS 9+): zayıf referans sayesinde sızıntı olmaz, ancak bildirim merkezi, açık removeObserver'a kadar bloğu bellekte tutmaya devam eder. Her zaman deinit'te gözlemciyi kaldırmanız veya otomatik yönetim için Token desenini kullanmanız önerilir.

NotificationCenter ve KVO arasındaki fark nedir?

NotificationCenter, ilgisiz bileşenler arasında rastgele olaylar için bir yayın mekanizmasıdır. KVO, belirli bir nesnenin belirli bir özelliğindeki değişiklikleri gözlemler. KVO, NSObject kalıtımı gerektirir ve setter aracılığıyla özellik değişikliklerinde otomatik olarak bildirir. NotificationCenter yalnızca post açıkça çağrıldığında bildirir. Model gözlemi için KVO veya Combine tercih edilir.

Bir uygulamada kaç tane NotificationCenter bulunur?

Uygulama işlemi başına bir default center. NotificationCenter() aracılığıyla ek merkezler oluşturulabilir, ancak pratikte paylaşılan default kullanılır. Her merkez bağımsız çalışır — birindeki post diğerinin gözlemcilerine iletilmez. Modül yalıtımı için, ters alan adlı bildirim adları aracılığıyla ayrı Name ad alanları kullanın.

Combine, NotificationCenter'ın yerini alır mı?

Kısmen. Combine, NotificationCenter'ı reaktif bir akışa saran NotificationCenter.Publisher sağlar. Combine, senkronizasyon sorununu (receive(on:) aracılığıyla) çözer, dönüşüm operatörleri ve otomatik abonelik yönetimi (AnyCancellable) ekler. Ancak NotificationCenter, iOS sistem bildirimleri (UIApplication, UIKeyboard) ve eski kod için kalır. Combine bir iyileştirmedir, bir yenileme değildir.

Özet

  • NotificationCenter — iOS'ta gevşek bağlı bire-çok iletişim için Observer deseninin bir uygulaması.
  • post, geçerli iş parçacığındaki tüm gözlemcilere senkron olarak bir bildirim gönderir ve göndereni bloklar.
  • addObserver, selector-based (@objc ile) ve block-based (capture list ve queue ile) aboneliği destekler.
  • removeObserver, selector-based abonelikler için deinit'te zorunludur, aksi takdirde çökme.
  • NotificationQueue, sık olaylar için coalescing ile gecikmeli teslimat sağlar.
  • İş parçacığı güvenliği, herhangi bir iş parçacığından çalışmayı garanti eder, ancak işleyiciler gönderenin iş parçacığında yürütülür.
  • Güvenli ve modern abonelik yönetimi için Token desenini veya Combine yayıncısını kullanın.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun