iOS va Android dasturida Method Swizzling: asosiy tushunchalar, texnikalar va ishlash prinsipi

Muallif: IT Sectr Nashr etilgan: 2026-05-17 O'qish vaqti: 9 daq

Method Swizzling — runtime texnikasi bo‘lib, unda sinfning ikki metodining implementatsiyalari bajarish vaqtida joylarini almashtiradi. U pastki sinf yaratmasdan va manba kodini o‘zgartirmasdan tizim metodining xatti-harakatini bekor qilish yoki kengaytirish imkonini beradi. Texnika eng ko‘p Objective-C da iOS dasturida qo‘llanilgan, ammo Kotlin/Android da reflection orqali o‘xshashlari mavjud. NSHipster Guide by Mattt, 2024 ma'lumotlariga ko‘ra, swizzling Objective-C Runtime ning eng kuchli, ammo eng xavfli mexanizmlaridan biridir.

Asosiy

  • Method Swizzling — sel_registerName va method_exchangeImplementations orqali runtime da ikkita Objective-C metodining implementatsiyalarini almashish.
  • Objective-C Runtime objc_msgSend va dispatch table orqali dinamik dispetcherizatsiya tufayli swizzling ni ta'minlaydi.
  • Android da Swizzling Java Reflection orqali dex-fayllarda implementatsiyani almashtirish yoki Gradle Transform API orqali amalga oshiriladi.
  • Swizzling xatarlari — kutubxonalar o'rtasidagi to‘qnashuvlar, iOS yangilanishlari bilan mos kelmaslik, metod imzolari o'zgarganda ishdan chiqish.
  • Xavfsiz swizzling dispatch_once, atomarlik va swizzled-metod ichida original implementatsiyani chaqirishni talab qiladi.

Method Swizzling nima?

Method Swizzling — ikki Objective-C metodining implementatsiyalarini bajarish vaqtida joylarini almashtiradigan runtime texnikasi. Swizzling dan so'ng originalSelector chaqiruvi swizzledSelector kodining bajarilishiga olib keladi va aksincha. Bu Objective-C Runtime arxitekturasi tufayli mumkin, bunda har bir selektor (SEL) dispatch table — bajarish vaqtida o‘zgartirilishi mumkin bo‘lgan jadval orqali implementatsiya (IMP) bilan bog‘langan.

«Swizzling» atamasi 2000-yillarning boshlarida Cocoa dasturchilari jamoasida kiritilgan. Texnika kutubxonalar tufayli keng tanildi: AFNetworking (yuklashni kuzatish uchun UIWebView swizzling), Aspects (swizzling ga asoslangan AOP framework) va FLEX (tekshirish uchun tizim metodlarini swizzle qiladigan disk raskadrovka vositasi). Bugun swizzling ko‘pchilik iOS ilovalarida bilvosita — monitoring va analitika kutubxonalari orqali qo‘llaniladi.

Swizzling ning muhim xususiyati — globallik: implementatsiyani almashtirish instansiya emas, sinf darajasida sodir bo‘ladi. Agar kutubxona UIViewController.viewDidLoad metodini swizzle qilsa, bu ilovadagi BARCHA UIViewController instansiyalariga, shu jumladan tizim instansiyalariga ta'sir qiladi. Bu bir vaqtning o‘zida swizzling ning kuchi — bir satr kod butun ilovaning xatti-harakatini o‘zgartiradi — va xatolarning asosiy manbai.

Objective-C da Method Swizzling qanday ishlaydi

Objective-C Runtime har bir sinfda dispatch table — kaliti SEL (metod identifikatori), qiymati IMP (implementatsiya funksiyasiga ko‘rsatgich) bo‘lgan lug‘atni saqlaydi. Ilova ob'ektga xabar yuborganda, objc_msgSend ushbu jadvalda chiziqli qidirishni amalga oshiradi. Method Swizzling bir SEL ning IMP sini boshqa SEL ning IMP si bilan almashtirib, chaqiruvlarni yo'naltiradi.

objective-c
// Xavfsiz method swizzling implementatsiyasi
@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

Asosiy funksiya — method_exchangeImplementations(Method, Method). U ikkita Method ob'ektining IMP sini atom tarzda almashtiradi. Chaqiruvdan so'ng sinfning dispatch table i o'zgaradi: original ga murojaat qilganda swizzled kodi, swizzled ga murojaat qilganda esa original kodi bajariladi. SafeSwizzle kategoriyasi ushbu metodni barcha NSObject ga qo'shib, istalgan sinfga swizzling ni bajarish imkonini beradi.

Xavfsiz swizzling implementatsiyasi swizzled versiyasi ichida original implementatsiyani chaqirishni talab qiladi. Aks holda metodning original xatti-harakati qaytarib bo'lmaydigan darajada yo'qoladi. To'g'ri namuna — almashishdan oldin original IMP ni saqlash va uni swizzled-metodda chaqirish:

objective-c
// Original implementatsiyani chaqirish bilan swizzling
- (void)swizzled_viewDidLoad {
    // 1. Original implementatsiyani chaqirish
    [self swizzled_viewDidLoad];

    // 2. Original chaqiruvdan keyin qo'shimcha mantiq
    NSLog("viewDidLoad bajarildi, swizzling faol");
}

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

dispatch_once swizzling ilovaning ishlash muddati davomida bir marta bajarilishini kafolatlaydi. Xuddi shu metodni qayta swizzle qilish cheksiz rekursiyaga olib keladi: swizzled metod o'zini-o'zi chaqiradi. +load sinf runtime ga yuklanganda chaqiriladi — bu ilovaning asosiy kodidan oldin bajariladigan swizzling uchun xavfsiz nuqta.

Dispatch table anatomiyasi

Objective-C dispatch table — SEL, IMP va qaytariladigan qiymat turini o'z ichiga olgan method_t strukturalari massivi. method_exchangeImplementations shunchaki ushbu jadvalda ikkita IMP ko'rsatgichini almashtiradi. Muhim: swizzling faqat sinf darajasida ishlaydi, protokol darajasida emas. Agar metod protokolda aniqlangan, lekin implementatsiya qilinmagan bo'lsa — dispatch table swizzling uchun yozuvni o'z ichiga olmaydi.

Swizzling ning unumdorlikka ta'siri

Swizzling ning yuki minimal — dispatch table da ikkita IMP ko'rsatgichini almashtirish bir necha nanosekund davom etadi. Swizzling dan keyin metod chaqiruvi sekinlashmaydi: objc_msgSend IMP ni swizzling dan oldingi kabi O(1) vaqtda topadi. Yagona qo'shimcha operatsiya — almashishdan keyin birinchi chaqiruvda method cache ni tekshirish. Apple Performance Team ma'lumotlariga ko'ra, swizzling ilovaning unumdorligiga ta'sir qilmaydi.

iOS da Method Swizzling qo'llanilishi

Method Swizzling uchta asosiy stsenariyda qo'llaniladi: monitoring va analitika (avtomatik hodisalarni jo'natish uchun viewDidLoad, viewDidAppear ni kuzatish), AOP tutib olish (metodning barcha chaqiruvlari parametrlarini qayd etish) va hotfix (JSPatch kabi kutubxonalar orqali App Store Review siz production da xatoni tuzatish).

  • Avtomatik analitika — har bir kontrollerda kodni takrorlamasdan screen view hodisasini jo'natish uchun UIViewController.viewDidAppear swizzling.
  • Tarmoq so'rovlarini qayd etish – barcha HTTP so'rovlarini, shu jumladan uchinchi tomon kutubxonalarini kuzatish uchun NSURLSession.resume swizzling.
  • AOP (Aspect-Oriented Programming) — Aspects kutubxonasi metodlarni swizzle qiladi va original chaqiruvdan oldin/keyin/o'rniga kod blokini bajaradi.
  • Hotfix — ilovani qayta qurmasdan xatoli metod implementatsiyasini tuzatilgan versiya bilan almashtirish (2020 dan App Review tomonidan taqiqlangan).
  • Test va moklar — OCMock unit testlarda metodlarni mock-implementatsiyalar bilan almashtirish uchun swizzling dan foydalanadi.

Ushbu stsenariylarning har biri swizzling markazlashtirilgan holda qo'llanilishi tufayli ishlaydi. Analitika kutubxonasi +load da bir marta swizzling ni bajaradi va ilovadagi barcha UIViewController hodisalarni jo'natishni boshlaydi. Dasturchi har bir kontrollerda kod qo'shishi shart emas — bu takrorlanishni va xato xavfini kamaytiradi.

Android da Method Swizzling: reflection va bytecode manipulation

Android da klassik Objective-C ma'nosida method swizzling mumkin emas — Java/Kotlin vtable orqali statik dispetcherizatsiyadan foydalanadi. Biroq, shunga o'xshash effektga erishadigan mexanizmlar mavjud: runtime da implementatsiyani almashtirish uchun Java Reflection va qurish bosqichida baytkodni o'zgartirish uchun Gradle Transform API / ASM.

kotlin
// Android da reflection + companion object orqali swizzling
class Logger {
    companion object {
        var originalImpl: (() -> Unit)? = null
    }

    fun log() {
        println("original log")
    }
}

// Runtime da reflection orqali implementatsiyani almashtirish
fun swizzleLog() {
    val originalMethod = Logger::class.java
        .getDeclaredMethod("log")
    originalMethod.isAccessible = true

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

    // Inline funksiya orqali almashtirish
    println("swizzled: log tutib olindi")
}

Bu kod Java Reflection orqali log() metodining xatti-harakatini o'zgartiradi: getDeclaredMethod xususiy implementatsiyaga kirishni oladi, isAccessible kirishni tekshirishni o'chiradi. To'g'ridan-to'g'ri log() chaqiruvi o'rniga qo'shimcha mantiqni bajaradigan o'rovchi chaqiriladi. Biroq, Android issiq metodlarni JIT orqali optimallashtiradi — reflection allaqachon kompilyatsiya qilingan AOT qismlarida ishlamasligi mumkin.

Ishonchliroq yondashuv — ASM kutubxonasi bilan Gradle Transform API yoki AGP (Android Gradle Plugin) orqali bytecode manipulation. Baytkodni o'zgartirish kompilyatsiya bosqichida amalga oshiriladi: ASM sinfning har bir metodiga chaqiruvlarni qo'shadi. Kod qamrovi vositalari (JaCoCo) va unumdorlik monitoringi (Firebase Performance Monitoring) shunday ishlaydi.

Method Swizzling xatarlari va best practices

Method Swizzling — yuqori xavfli texnika. Kutubxonalar o'rtasidagi to'qnashuvlar: agar ikki kutubxona bir xil metodni swizzle qilsa, bajarish tartibi kafolatlanmaydi. iOS yangilanishlari bilan mos kelmaslik: Apple yangi iOS versiyasida imzoni o'zgartirsa yoki metodni o'chirsa, swizzling ishdan chiqishga olib keladi. Kodda ko'rinmaslik: swizzling sinf implementatsiyasida ko'rinmaydi, bu disk raskadrovkani qiyinlashtiradi.

XatarTavsifKamaytirish
Kutubxona to'qnashuviIkki kutubxona viewDidAppear ni swizzle qiladi — biri ikkinchisini buzadiMetod allaqachon swizzle qilinganligini class_getInstanceMethod orqali tekshiring
RekursiyaXuddi shu metodni qayta swizzle qilish cheksiz aylanishga sabab bo'ladiHar doim dispatch_once dan foydalaning
Imzo o'zgarishiApple yangi iOS da metod imzosini o'zgartiradi — IMP mos kelmaydiBarcha qo'llab-quvvatlanadigan iOS versiyalarida test qiling
Ko'rinmaslikSwizzling Xcode chaqiruv stekida ko'rsatilmaydiBarcha swizzling operatsiyalarini kodda hujjatlashtiring
App ReviewApple hujjatlashtirilmagan swizzling bilan ilovalarni rad etadiFaqat ommaviy API lardan foydalaning va maqsadni hujjatlashtiring

Best practices xavfsiz swizzling uchun quyidagilarni o'z ichiga oladi: har doim original implementatsiyani chaqiring, swizzling ni +load da dispatch_once orqali bajaring, swizzled-metodlarni prefiks bilan nomlang (masalan, s_originalMethodName), har bir swizzling operatsiyasini maqsadini ko'rsatib hujjatlashtiring. Aspects kutubxonasi to'qnashuvlar muammosini original metoddan oldin/keyin bloklarni zanjirli bajarish orqali hal qiladi.

Zamonaviy dasturda Method Swizzling ga alternativlar

Method swizzling ga alternativlar bashorat qilish mumkinligi va xavfsizligi sababli production kodi uchun afzalroqdir. Delegatlar va protokollar (UIApplicationDelegate, UITableViewDelegate) runtime ni o'zgartirmasdan aniq kengaytirish nuqtalarini ta'minlaydi. Pastki sinflar — viewDidAppear ni bekor qilish bilan UIViewController pastki sinfini yaratish — bashorat qilish mumkin bo'lgan tarzda ishlaydi va to'qnashuvlarga ega emas.

SwiftUI va Combine swizzling ga bo'lgan ehtiyojni yo'q qiladi: modifikatorlar (onAppear, onChange) metodlarni bekor qilmasdan deklarativ tarzda xatti-harakat qo'shadi. Android Jetpack Compose da xuddi shu effektga effektlar (LaunchedEffect, SideEffect) va modifikatorlar orqali erishiladi. AOP frameworklari (Android uchun AspectJ, iOS uchun InterposeKit) compile-time weaving bilan xavfsiz alternativani ta'minlaydi.

Apple WWDC 2024 ma'lumotlariga ko'ra, Swift runtime til darajasida method swizzling ni qo'llab-quvvatlamaydi — @objc dynamic metodlar faqat Objective-C Runtime orqali swizzle qilinishi mumkin. @objc dan foydalanmaydigan Swift ilovalari uchinchi tomon kutubxonalari tomonidan tasodifiy swizzling dan to'liq himoyalangan. Bu Swift ni xavfsizroq qiladi, ammo runtime instrumentalizasiya imkoniyatlarini cheklaydi.

SwiftUI va Compose da deklarativ alternativlar

SwiftUI modifikatorlari (onAppear, onChange, onReceive) va Jetpack Compose effektlari (LaunchedEffect, SideEffect, DisposableEffect) UI vazifalari uchun swizzling ni to'liq almashtiradi. Ular dispatch table ni o'zgartirmasdan kesishuvchi xatti-harakat qo'shishning deklarativ, bashorat qilish mumkin bo'lgan va tekshiriladigan usulini ta'minlaydi. Yangi loyihalarda Apple va Google runtime tutib olish o'rniga aynan shu yondashuvni tavsiya qiladi.

Tez-tez so'raladigan savollar

Method Swizzling production uchun xavfsizmi?

Method Swizzling qoidalarga rioya qilingan holda production uchun maqbuldir: bir martalik bajarish uchun dispatch_once, original implementatsiyani chaqirish, barcha iOS versiyalarida test qilish va hujjatlashtirish. Oddiy vazifalar uchun delegatlar yoki pastki sinflardan foydalanish yaxshiroqdir. Production da Swizzling monitoring va analitika kutubxonalari uchun asoslanadi.

Swizzling AOP dan qanday farq qiladi?

Method Swizzling — dispatch table da IMP ni almashtirishning aniq texnikasi. AOP (Aspect-Oriented Programming) — swizzling mexanizmlardan biri sifatida ishlatilishi mumkin bo'lgan paradigmadir. AOP shuningdek compile-time weaving (AspectJ), proxy-ga asoslangan tutib olish (Spring AOP) va code generation ni o'z ichiga oladi.

Swizzling sabab bo'lgan muammolarni qanday disk raskadrovka qilish kerak?

Barcha xabarlarni kuzatish uchun objc_msgSend da breakpoint dan foydalaning. Sinf nomi sharti bilan method_exchangeImplementations ga ramziy breakpoint qo'shing. FLEX vositasi sinfning qaysi metodlari swizzle qilinganligini ko'rsatadi. Tizimli tekshirish uchun sinfning dispatch table ini ko'rsatadigan lldb skriptidan foydalaning.

Swizzling Swift da ishlaydimi?

Swift til darajasida swizzling ni qo'llab-quvvatlamaydi. Method Swizzling faqat @objc dynamic bilan belgilangan, Objective-C Runtime orqali kompilyatsiya qilinadigan metodlar uchun ishlaydi. Sof Swift metodlari (@objc holda) statik dispetcherizatsiyadan foydalanadi va swizzle qilinishi mumkin emas — ularning dispatch table i o'zgartirish uchun mavjud emas.

Qaysi iOS kutubxonalari Swizzling dan foydalanadi?

Firebase Analytics (avtomatik ekran kuzatuvi uchun viewDidAppear swizzling), Amplitude, Mixpanel, FLEX (UI tekshiruvi), OHHTTPStubs (tarmoq so'rovlarini moklash), Aspects (AOP framework). Hammasi original implementatsiyani chaqirish bilan dispatch_once orqali +load da swizzling ni bajaradi.

Xulosa

  • Method Swizzling — method_exchangeImplementations orqali Objective-C Runtime dispatch table ida ikki metodning IMP sini almashish.
  • dispatch_once qayta swizzling va rekursiyaning oldini olish uchun majburiydir.
  • Original implementatsiyani chaqirish swizzled-metod ichida — majburiy xavfsizlik qoidasi.
  • Android da swizzling reflection yoki Gradle Transform / ASM orqali bytecode manipulation bilan almashtiriladi.
  • Xatarlar — kutubxona to'qnashuvlari, iOS versiyalari bilan mos kelmaslik, diskgrerda ko'rinmaslik va hotfix uchun App Review taqiqi.
  • Alternativlar — delegatlar, pastki sinflar, SwiftUI modifikatorlari, Jetpack Compose effektlari.
  • @objc dynamic siz Swift metodlari swizzling dan himoyalangan, bu barqarorlikni oshiradi, ammo runtime instrumentalizasiyani cheklaydi.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing