iOS ve Android Geliştirmede Method Swizzling: Temel Kavramlar, Teknikler ve Çalışma Prensibi

Yazar: IT Sectr Yayınlanma: 2026-05-17 Okuma süresi: 9 dk

Method Swizzling, iki sınıf metodunun uygulamalarının çalışma zamanında yer değiştirdiği bir runtime tekniğidir. Bir alt sınıf oluşturmadan veya kaynak kodu değiştirmeden sistem metodunun davranışını geçersiz kılmayı veya tamamlamayı sağlar. Bu teknik en büyük uygulamasını Objective-C ile iOS geliştirmede bulmuştur, ancak Kotlin/Android'de yansıma yoluyla benzerleri mevcuttur. NSHipster Guide by Mattt, 2024'e göre, swizzling Objective-C Runtime'ın en güçlü ama aynı zamanda en tehlikeli mekanizmalarından biridir.

Ana Noktalar

  • Method Swizzling — sel_registerName ve method_exchangeImplementations aracılığıyla runtime'da iki Objective-C metodunun uygulamalarının değiştirilmesi.
  • Objective-C Runtime, objc_msgSend ve dispatch tablosu aracılığıyla dinamik dağıtım sayesinde swizzling'i mümkün kılar.
  • Android'de Swizzling, Java Reflection aracılığıyla dex dosyalarında uygulama değiştirme veya Gradle Transform API ile gerçekleştirilir.
  • Swizzling riskleri — kütüphaneler arasında çakışmalar, iOS güncellemeleriyle uyumsuzluk, metot imzaları değiştiğinde çökmeler.
  • Güvenli swizzling, dispatch_once, atomiklik ve swizzled metot içinde orijinal uygulamanın çağrılmasını gerektirir.

Method Swizzling Nedir?

Method Swizzling, iki Objective-C metodunun uygulamalarını değiştiren bir runtime tekniğidir. Swizzling'den sonra, originalSelector'ı çağırmak swizzledSelector'ın kodunu çalıştırır ve bunun tersi de geçerlidir. Bu, her seçicinin (SEL) bir dispatch tablosu aracılığıyla bir uygulamaya (IMP) bağlı olduğu Objective-C Runtime mimarisi sayesinde mümkündür — çalışma zamanında değiştirilebilen bir tablo.

“swizzling” terimi, 2000'lerin başında Cocoa geliştirici topluluğunda tanıtılmıştır. Teknik, şu kütüphaneler sayesinde geniş çapta tanınmıştır: AFNetworking (yüklemeyi izlemek için UIWebView swizzling'i), Aspects (swizzling tabanlı AOP çerçevesi) ve FLEX (inceleme için sistem metotlarını swizzle eden hata ayıklama aracı). Günümüzde swizzling, çoğu iOS uygulamasında örtülü olarak — izleme ve analiz kütüphaneleri aracılığıyla — kullanılmaktadır.

Swizzling'in önemli bir özelliği küreselliktir: uygulama değişimi örnek düzeyinde değil, sınıf düzeyinde gerçekleşir. Bir kütüphane UIViewController.viewDidLoad metodunu swizzle ederse, bu sisteminkiler de dahil olmak üzere uygulamadaki TÜM UIViewController örneklerini etkiler. Bu, swizzling'in gücü — tek bir kod satırı tüm uygulamanın davranışını değiştirir — ve aynı zamanda hataların ana kaynağıdır.

Objective-C'de Method Swizzling Nasıl Çalışır

Objective-C Runtime, her sınıfta bir dispatch tablosu saklar — anahtarı SEL (metot tanımlayıcısı) ve değeri IMP (uygulama fonksiyonunun işaretçisi) olan bir sözlük. Bir uygulama bir nesneye mesaj gönderdiğinde, objc_msgSend bu tabloda doğrusal bir arama yapar. Method Swizzling, bir SEL'in IMP'sini başka bir SEL'in IMP'siyle değiştirerek çağrıları yönlendirir.

objective-c
// Güvenli method swizzling uygulaması
@implementation NSObject (SafeSwizzle)

+ (void)swizzleClassMethod:(SEL)original
                  with:(SEL)swizzled {
    Class cls = [self class];
    SEL originalSel = original;
    SEL swizzledSel = swizzled;

    Method originalMethod = class_getInstanceMethod(cls, originalSel);
    Method swizzledMethod = class_getInstanceMethod(cls, swizzledSel);

    method_exchangeImplementations(originalMethod, swizzledMethod);
}

@end

Anahtar işlev method_exchangeImplementations(Method, Method)'dur. İki Method nesnesinin IMP'lerini atomik olarak değiştirir. Çağrıdan sonra, sınıfın dispatch tablosu değiştirilir: original çağrıldığında swizzled kodu, swizzled çağrıldığında original kodu çalıştırılır. SafeSwizzle kategorisi bu metodu tüm NSObject'lere ekleyerek herhangi bir sınıfın swizzling yapmasına olanak tanır.

Güvenli bir swizzling uygulaması, swizzled sürümün içinde orijinal uygulamayı çağırmayı gerektirir. Aksi takdirde, metodun orijinal davranışı geri döndürülemez şekilde kaybolur. Doğru desen, değişimden önce orijinal IMP'yi kaydetmek ve swizzled metot içinde çağırmaktır:

objective-c
// Orijinal uygulama çağrısı ile Swizzling
- (void)swizzled_viewDidLoad {
    // 1. Orijinal uygulamayı çağırma
    [self swizzled_viewDidLoad];

    // 2. Orijinal çağrıdan sonra ek mantık
    NSLog("viewDidLoad çalıştırıldı, swizzling aktif");
}

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleClassMethod:@selector(viewDidLoad)
                            with:@selector(swizzled_viewDidLoad)];
    });
}

dispatch_once, swizzling'in uygulamanın ömrü boyunca tam olarak bir kez çalıştırılmasını garanti eder. Aynı metodu yeniden swizzle'lamak sonsuz özyinelemeye yol açar: swizzled metot kendisini çağırır. +load, sınıf runtime'a yüklendiğinde çağrılır — bu, ana uygulama kodundan önce çalışan swizzling için güvenli bir noktadır.

Dispatch Tablosunun Anatomisi

Bir Objective-C sınıfının dispatch tablosu, SEL, IMP ve dönüş türünü içeren method_t yapılarının bir dizisidir. method_exchangeImplementations basitçe bu tablodaki iki IMP işaretçisini değiştirir. Önemli: swizzling yalnızca sınıf düzeyinde çalışır, protokol düzeyinde çalışmaz. Bir metot protokolde tanımlanmış ancak uygulanmamışsa, dispatch tablosu swizzling için bir giriş içermez.

Swizzling'in Performans Üzerindeki Etkisi

Swizzling ek yükü minimumdur — dispatch tablosunda iki IMP işaretçisini değiştirmek birkaç nanosaniye sürer. Swizzling'den sonra, metot dağıtımı yavaşlamaz: objc_msgSend, swizzling'den öncekiyle aynı O(1) sürede IMP'yi bulur. Tek ek işlem, değişimden sonraki ilk çağrıda metot önbellek kontrolüdür. Apple Performance Team verilerine göre, swizzling uygulama performansını etkilemez.

iOS'te Method Swizzling Kullanım Alanları

Method Swizzling üç ana senaryoda kullanılır: izleme ve analiz (otomatik etkinlik gönderimi için viewDidLoad, viewDidAppear takibi), AOP müdahalesi (tüm metot çağrılarının parametrelerinin günlüğe kaydedilmesi) ve hotfix (JSPatch gibi kütüphaneler aracılığıyla App Store Review olmadan üretim hatasının düzeltilmesi).

  • Otomatik analiz — her denetleyicide kodu tekrarlamadan ekran görünümü etkinlikleri göndermek için UIViewController.viewDidAppear swizzling'i.
  • Ağ isteği günlüğü — üçüncü taraf kütüphaneler de dahil olmak üzere tüm HTTP isteklerini izlemek için NSURLSession.resume swizzling'i.
  • AOP (Yönelim Odaklı Programlama) — Aspects kütüphanesi metotları swizzle eder ve orijinal çağrıdan önce/sonra/yerine bir kod bloğu çalıştırır.
  • Hotfix — uygulamayı yeniden derlemeden hatalı bir metodun uygulamasını düzeltilmiş olanla değiştirme (2020'den beri App Review tarafından yasaklanmıştır).
  • Test ve mock'lar — OCMock, birim testlerinde metotları mock uygulamalarla değiştirmek için swizzling kullanır.

Bu senaryoların her biri, swizzling'in merkezi olarak uygulanması sayesinde çalışır. Bir analiz kütüphanesi +load'da bir kez swizzling yapar ve uygulamadaki tüm UIViewController örnekleri etkinlik göndermeye başlar. Geliştiricinin her denetleyiciye kod eklemesi gerekmez — bu, tekrarı ve hata riskini azaltır.

Android'de Method Swizzling: Yansıma ve Bayt Kodu Manipülasyonu

Android'de, klasik Objective-C anlamında method swizzling mümkün değildir — Java/Kotlin, vtable aracılığıyla statik dağıtım kullanır. Ancak, benzer bir etki elde eden mekanizmalar mevcuttur: çalışma zamanında uygulama değişimi için Java Yansıması ve derleme zamanında bayt kodu değişikliği için Gradle Transform API / ASM.

kotlin
// Android'de yansıma + companion object aracılığıyla Swizzling
class Logger {
    companion object {
        var originalImpl: (() -> Unit)? = null
    }

    fun log() {
        println("orijinal günlük")
    }
}

// Runtime'da yansıma yoluyla uygulama değişimi
fun swizzleLog() {
    val originalMethod = Logger::class.java
        .getDeclaredMethod("log")
    originalMethod.isAccessible = true

    Logger.originalImpl = {
        originalMethod.invoke(Logger())
    }

    // Satır içi işlev aracılığıyla değiştirme
    println("swizzled: günlük ele geçirildi")
}

Bu kod, Java Yansıması aracılığıyla log() metodunun davranışını değiştirir: getDeclaredMethod özel uygulamaya erişir, isAccessible erişim kontrollerini devre dışı bırakır. Doğrudan log() çağırmak yerine, ek mantık yürüten bir sarmalayıcı çağrılır. Ancak Android, JIT aracılığıyla sıcak metotları optimize eder — yansıma, önceden derlenmiş AOT segmentlerinde çalışmayabilir.

Daha güvenilir bir yaklaşım, ASM kütüphanesi ile Gradle Transform API veya AGP (Android Gradle Plugin) aracılığıyla bayt kodu manipülasyonudur. Bayt kodu değişikliği derleme zamanında gerçekleştirilir: ASM, sınıfın her metoduna çağrı ekler. Kod kapsamı araçları (JaCoCo) ve performans izleme araçları (Firebase Performance Monitoring) bu şekilde çalışır.

Method Swizzling Riskleri ve En İyi Uygulamalar

Method Swizzling yüksek riskli bir tekniktir. Kütüphaneler arasında çakışmalar: iki kütüphane aynı metodu swizzle ederse, yürütme sırası garanti edilmez. iOS güncellemeleriyle uyumsuzluk: Apple yeni bir iOS sürümünde imzayı değiştirir veya bir metodu kaldırırsa, swizzling çökmelere yol açar. Kodda görünürlük eksikliği: swizzling sınıf uygulamasında görünmez, bu da hata ayıklamayı zorlaştırır.

RiskAçıklamaAzaltma
Kütüphane çakışmasıİki kütüphane viewDidAppear'ı swizzler — biri diğerini bozarclass_getInstanceMethod ile metodun zaten swizzlenmiş olup olmadığını kontrol edin
ÖzyinelemeAynı metodu yeniden swizzle'lamak sonsuz döngüye neden olurHer zaman dispatch_once kullanın
İmza değişikliğiApple yeni iOS'te metot imzasını değiştirir — IMP uyuşmazlığıDesteklenen tüm iOS sürümlerinde test edin
GörünmezlikSwizzling Xcode çağrı yığınında görünmezTüm swizzling işlemlerini kodda belgeleyin
App ReviewApple belgelenmemiş swizzling içeren uygulamaları reddederYalnızca genel API'leri kullanın ve amacı belgeleyin

Güvenli swizzling için en iyi uygulamalar şunları içerir: her zaman orijinal uygulamayı çağırın, swizzling'i dispatch_once aracılığıyla +load'da kesinlikle gerçekleştirin, swizzlenmiş metotları bir ön ekle adlandırın (örneğin, s_originalMethodName), her swizzling işlemini amacıyla birlikte belgeleyin. Aspects kütüphanesi, orijinal metottan önce/sonra blokların zincirleme yürütülmesi yoluyla çakışma sorununu çözer.

Modern Geliştirmede Method Swizzling Alternatifleri

Method swizzling alternatifleri, öngörülebilirlik ve güvenlik nedeniyle üretim kodu için tercih edilir. Temsilciler ve protokoller (UIApplicationDelegate, UITableViewDelegate) runtime'ı değiştirmeden açık genişleme noktaları sağlar. Alt sınıf oluşturma — viewDidAppear'ı geçersiz kılan bir UIViewController alt sınıfı oluşturma — öngörülebilir şekilde çalışır ve çakışmaları yoktur.

SwiftUI ve Combine, swizzling ihtiyacını ortadan kaldırır: değiştiriciler (onAppear, onChange) metotları geçersiz kılmadan bildirimsel olarak davranış ekler. Android Jetpack Compose'da aynı şey etkiler (LaunchedEffect, SideEffect) ve değiştiriciler aracılığıyla elde edilir. AOP çerçeveleri (Android için AspectJ, iOS için InterposeKit) derleme zamanı örgüsü ile güvenli bir alternatif sunar.

Apple WWDC 2024 verilerine göre, Swift runtime dil düzeyinde method swizzling'i desteklemez — @objc dynamic metotlar yalnızca Objective-C Runtime aracılığıyla swizzlenebilir. @objc kullanmayan Swift uygulamaları, üçüncü taraf kütüphaneler tarafından yanlışlıkla yapılan swizzling'den tamamen korunur. Bu, Swift'i daha güvenli kılar ancak runtime enstrümantasyon yeteneklerini sınırlar.

SwiftUI ve Compose'ta Bildirimsel Alternatifler

SwiftUI değiştiricileri (onAppear, onChange, onReceive) ve Jetpack Compose etkileri (LaunchedEffect, SideEffect, DisposableEffect), UI görevleri için swizzling'in yerini tamamen alır. Dispatch tablosunu değiştirmeden kesişen davranış eklemek için bildirimsel, öngörülebilir ve test edilebilir bir yol sağlarlar. Yeni projelerde Apple ve Google, runtime müdahalesi yerine bu yaklaşımı önermektedir.

Sıkça Sorulan Sorular

Method Swizzling üretim için güvenli midir?

Method Swizzling, kurallara uyulduğunda üretim için kabul edilebilir: tek seferlik çalıştırma için dispatch_once, orijinal uygulamayı çağırma, tüm iOS sürümlerinde test etme ve belgeleme. Basit görevler için temsilciler veya alt sınıf oluşturma kullanmak daha iyidir. Üretimde Swizzling, izleme ve analiz kütüphaneleri için haklıdır.

Swizzling, AOP'den nasıl farklıdır?

Method Swizzling, dispatch tablosunda IMP'leri değiştirmek için belirli bir tekniktir. AOP (Yönelim Odaklı Programlama), swizzling'in mekanizmalardan biri olarak kullanılabileceği bir paradigmadır. AOP ayrıca derleme zamanı örgüsü (AspectJ), proxy tabanlı müdahale (Spring AOP) ve kod oluşturmayı da içerir.

Swizzling'in neden olduğu sorunlar nasıl hata ayıklanır?

Tüm mesajları izlemek için objc_msgSend'te bir kesme noktası kullanın. Sınıf adına koşullu olarak method_exchangeImplementations üzerinde sembolik bir kesme noktası ekleyin. FLEX aracı, sınıfın hangi metotlarının swizzlenmiş olduğunu gösterir. Sistematik kontrol için, sınıfın dispatch tablosunu çıkaran bir lldb betiği kullanın.

Swizzling Swift'te çalışır mı?

Swift, dil düzeyinde swizzling'i desteklemez. Method Swizzling yalnızca @objc dynamic ile işaretlenmiş metotlar için çalışır ve bunlar Objective-C Runtime aracılığıyla derlenir. Saf Swift metotları (@objc olmadan) statik dağıtım kullanır ve swizzlenemez — dispatch tabloları değişiklik için erişilebilir değildir.

Hangi iOS kütüphaneleri Swizzling kullanır?

Firebase Analytics (otomatik ekran izleme için viewDidAppear swizzling'i), Amplitude, Mixpanel, FLEX (UI incelemesi), OHHTTPStubs (ağ isteği simülasyonu), Aspects (AOP çerçevesi). Hepsi, orijinal uygulamayı çağırarak dispatch_once aracılığıyla +load'da swizzling gerçekleştirir.

Özet

  • Method Swizzling — method_exchangeImplementations aracılığıyla Objective-C Runtime dispatch tablosunda iki metodun IMP'lerinin değiştirilmesi.
  • dispatch_once, yeniden swizzle'lamayı ve özyinelemeyi önlemek için zorunludur.
  • Orijinal uygulamayı çağırmak, swizzlenmiş metot içinde zorunlu bir güvenlik kuralıdır.
  • Android'de, swizzling'in yerini Gradle Transform / ASM aracılığıyla yansıma veya bayt kodu manipülasyonu alır.
  • Riskler — kütüphane çakışmaları, iOS sürümleriyle uyumsuzluk, hata ayıklayıcıda görünmezlik ve hotfix'ler için App Review yasağı.
  • Alternatifler — temsilciler, alt sınıf oluşturma, SwiftUI değiştiricileri, Jetpack Compose etkileri.
  • @objc dynamic olmayan Swift metotları swizzling'den korunur, bu kararlılığı artırır ancak runtime enstrümantasyonunu sınırlar.

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