iOS اور Android ڈیولپمنٹ میں Method Swizzling: کلیدی تصورات، تکنیکیں اور کام کرنے کا اصول

مصنف: IT Sectr اشاعت: 2026-05-17 مطالعے کا وقت: 9 منٹ

Method Swizzling ایک رن ٹائم تکنیک ہے جس میں دو کلاس طریقوں کے نفاذ کو عملدرآمد کے دوران آپس میں تبدیل کیا جاتا ہے۔ یہ سب کلاس بنائے یا سورس کوڈ میں تبدیلی کیے بغیر سسٹم طریقہ کار کے رویے کو اوور رائڈ یا مکمل کرنے کی اجازت دیتا ہے۔ اس تکنیک کا سب سے زیادہ استعمال iOS ڈیولپمنٹ میں Objective-C کے ساتھ ہوا ہے، لیکن Kotlin/Android میں ریفلیکشن کے ذریعے مشابہ طریقے موجود ہیں۔ NSHipster Guide by Mattt, 2024 کے مطابق، swizzling Objective-C Runtime کے سب سے طاقتور لیکن سب سے خطرناک میکانزم میں سے ایک ہے۔

اہم نکات

  • Method Swizzling — sel_registerName اور method_exchangeImplementations کے ذریعے رن ٹائم میں دو Objective-C طریقوں کے نفاذ کا تبادلہ۔
  • Objective-C Runtime objc_msgSend اور ڈسپیچ ٹیبل کے ذریعے متحرک تقسیم کی بدولت swizzling کو ممکن بناتا ہے۔
  • Android پر Swizzling Java Reflection کے ذریعے dex فائلوں میں نفاذ کی تبدیلی یا Gradle Transform API کے ذریعے لاگو کیا جاتا ہے۔
  • Swizzling کے خطرات — لائبریریوں کے درمیان تنازعات، iOS اپ ڈیٹس کے ساتھ عدم مطابقت، طریقوں کے دستخط تبدیل ہونے پر کریش۔
  • محفوظ swizzling کے لیے dispatch_once، ایٹمییت اور swizzled طریقہ کے اندر اصل نفاذ کو کال کرنا ضروری ہے۔

Method Swizzling کیا ہے؟

Method Swizzling ایک رن ٹائم تکنیک ہے جو دو Objective-C طریقوں کے نفاذ کو آپس میں تبدیل کرتی ہے۔ Swizzling کے بعد، originalSelector کو کال کرنے سے swizzledSelector کا کوڈ عملدرآمد ہوتا ہے، اور اس کے برعکس بھی۔ یہ Objective-C Runtime کے فن تعمیر کی بدولت ممکن ہے، جہاں ہر سلیکٹر (SEL) ایک ڈسپیچ ٹیبل کے ذریعے ایک نفاذ (IMP) سے منسلک ہوتا ہے — ایک جدول جسے عملدرآمد کے دوران تبدیل کیا جا سکتا ہے۔

“swizzling” کی اصطلاح 2000 کی دہائی کے اوائل میں Cocoa ڈیولپر کمیونٹی میں متعارف کرائی گئی تھی۔ اس تکنیک کو لائبریریوں جیسے: AFNetworking (لوڈنگ ٹریک کرنے کے لیے UIWebView کا swizzling)، Aspects (swizzling پر مبنی AOP فریم ورک) اور FLEX (معائنہ کے لیے سسٹم طریقوں کو swizzle کرنے والا ڈیبگنگ ٹول) کی بدولت وسیع پہچان ملی۔ آج، swizzling زیادہ تر iOS ایپلیکیشنز میں بلاواسطہ استعمال ہوتا ہے — مانیٹرنگ اور اینالیٹکس لائبریریوں کے ذریعے۔

Swizzling کی ایک اہم خصوصیت عالمگیریت ہے: نفاذ کی تبدیلی انسٹینس سطح پر نہیں، بلکہ کلاس سطح پر ہوتی ہے۔ اگر کوئی لائبریری UIViewController.viewDidLoad طریقہ کو swizzle کرتی ہے، تو یہ ایپلیکیشن میں UIViewController کے تمام انسٹینسز کو متاثر کرتی ہے، بشمول سسٹم والے۔ یہ swizzling کی طاقت ہے — کوڈ کی ایک لائن پوری ایپلیکیشن کے رویے کو تبدیل کر دیتی ہے — اور بگز کا بنیادی ذریعہ بھی۔

Objective-C میں Method Swizzling کیسے کام کرتا ہے

Objective-C Runtime ہر کلاس میں ایک ڈسپیچ ٹیبل محفوظ کرتا ہے — ایک لغت جہاں کلید SEL (طریقہ شناخت کنندہ) ہے اور قدر IMP (نفاذ فنکشن کا پوائنٹر) ہے۔ جب کوئی ایپلیکیشن کسی آبجیکٹ کو پیغام بھیجتی ہے، تو objc_msgSend اس ٹیبل میں لکیری تلاش کرتا ہے۔ Method Swizzling ایک SEL کے IMP کو دوسرے SEL کے IMP سے بدل دیتا ہے، کالز کو ری ڈائریکٹ کرتا ہے۔

objective-c
// محفوظ method swizzling کا نفاذ
@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

اہم فنکشن method_exchangeImplementations(Method, Method) ہے۔ یہ دو Method آبجیکٹس کے IMPs کو ایٹمی طور پر تبدیل کرتا ہے۔ کال کے بعد، کلاس کا ڈسپیچ ٹیبل تبدیل ہو جاتا ہے: original کو کال کرنے سے swizzled کوڈ، swizzled کو کال کرنے سے original کوڈ عملدرآمد ہوتا ہے۔ SafeSwizzle زمرہ اس طریقہ کو تمام NSObject میں شامل کرتا ہے، جس سے کوئی بھی کلاس swizzling کر سکتی ہے۔

محفوظ swizzling نفاذ کے لیے swizzled ورژن کے اندر اصل نفاذ کو کال کرنا ضروری ہے۔ ورنہ، طریقہ کا اصل رویہ مستقل طور پر کھو جاتا ہے۔ صحیح نمونہ یہ ہے کہ تبادلے سے پہلے اصل IMP کو محفوظ کریں اور swizzled طریقہ میں اسے کال کریں:

objective-c
// اصل نفاذ کال کے ساتھ Swizzling
- (void)swizzled_viewDidLoad {
    // 1. اصل نفاذ کو کال کرنا
    [self swizzled_viewDidLoad];

    // 2. اصل کال کے بعد اضافی منطق
    NSLog("viewDidLoad عملدرآمد ہوا، swizzling فعال");
}

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

dispatch_once اس بات کی ضمانت دیتا ہے کہ swizzling ایپلیکیشن کی زندگی میں بالکل ایک بار عملدرآمد ہوتا ہے۔ اسی طریقہ کو دوبارہ swizzle کرنے سے لامحدود تکرار ہوگی: swizzled طریقہ خود کو کال کرے گا۔ +load کو کلاس کے رن ٹائم میں لوڈ ہونے پر کال کیا جاتا ہے — یہ swizzling کے لیے ایک محفوظ نقطہ ہے جو مرکزی ایپلیکیشن کوڈ سے پہلے عملدرآمد ہوتا ہے۔

ڈسپیچ ٹیبل کی ساخت

Objective-C کلاس کا ڈسپیچ ٹیبل method_t ڈھانچوں کی ایک صف ہے جس میں SEL، IMP اور واپسی کی قسم ہوتی ہے۔ method_exchangeImplementations صرف اس ٹیبل میں دو IMP پوائنٹرز کو تبدیل کرتا ہے۔ اہم: swizzling صرف کلاس سطح پر کام کرتا ہے، پروٹوکول سطح پر نہیں۔ اگر کوئی طریقہ پروٹوکول میں متعین ہے لیکن نافذ نہیں ہے، تو ڈسپیچ ٹیبل میں swizzling کے لیے کوئی اندراج نہیں ہوتا۔

کارکردگی پر Swizzling کا اثر

Swizzling کا اضافی بوجھ کم سے کم ہے — ڈسپیچ ٹیبل میں دو IMP پوائنٹرز کو تبدیل کرنے میں چند نینو سیکنڈ لگتے ہیں۔ Swizzling کے بعد، طریقہ کی تقسیم سست نہیں ہوتی: objc_msgSend swizzling سے پہلے کی طرح اسی O(1) وقت میں IMP ڈھونڈتا ہے۔ واحد اضافی عمل تبادلے کے بعد پہلی کال پر طریقہ کیش چیک ہے۔ Apple Performance Team کے اعداد و شمار کے مطابق، swizzling ایپلیکیشن کی کارکردگی کو متاثر نہیں کرتا۔

iOS میں Method Swizzling کے استعمالات

Method Swizzling تین اہم منظرناموں میں استعمال ہوتا ہے: مانیٹرنگ اور اینالیٹکس (خودکار ایونٹ بھیجنے کے لیے viewDidLoad، viewDidAppear کی ٹریکنگ)، AOP مداخلت (تمام طریقہ کالز کے پیرامیٹرز لاگ کرنا)، اور ہاٹ فکس (JSPatch جیسی لائبریریوں کے ذریعے App Store Review کے بغیر پروڈکشن بگ کو ٹھیک کرنا)۔

  • خودکار اینالیٹکس — ہر کنٹرولر میں کوڈ کو نقل کیے بغیر اسکرین ویو ایونٹس بھیجنے کے لیے UIViewController.viewDidAppear کا swizzling۔
  • نیٹ ورک درخواست لاگنگ — تیسرے فریق کی لائبریریوں سمیت تمام HTTP درخواستوں کو ٹریک کرنے کے لیے NSURLSession.resume کا swizzling۔
  • AOP (پہلو پر مبنی پروگرامنگ) — Aspects لائبریری طریقوں کو swizzle کرتی ہے اور اصل کال سے پہلے/بعد/بجائے کوڈ کا ایک بلاک چلاتی ہے۔
  • ہاٹ فکس — ایپلیکیشن کو دوبارہ بنائے بغیر بگ والے طریقہ کے نفاذ کو درست شدہ سے بدلنا (2020 سے App Review کے ذریعے ممنوع)۔
  • ٹیسٹنگ اور موک — OCMock یونٹ ٹیسٹوں میں طریقوں کو موک نفاذ سے بدلنے کے لیے swizzling استعمال کرتا ہے۔

ان میں سے ہر منظرنامہ اس لیے کام کرتا ہے کیونکہ swizzling مرکزی طور پر لاگو کیا جاتا ہے۔ ایک اینالیٹکس لائبریری +load میں ایک بار swizzling کرتی ہے، اور ایپلیکیشن میں UIViewController کے تمام انسٹینسز ایونٹس بھیجنا شروع کر دیتے ہیں۔ ڈیولپر کو ہر کنٹرولر میں کوڈ شامل کرنے کی ضرورت نہیں — اس سے تکرار اور خرابیوں کا خطرہ کم ہوتا ہے۔

Android پر Method Swizzling: ریفلیکشن اور بائٹ کوڈ ہیرا پھیری

Android پر، کلاسک Objective-C معنوں میں method swizzling ناممکن ہے — Java/Kotlin vtable کے ذریعے جامد تقسیم استعمال کرتے ہیں۔ تاہم، ایسے میکانزم موجود ہیں جو ایک جیسا اثر حاصل کرتے ہیں: رن ٹائم پر نفاذ کی تبدیلی کے لیے Java ریفلیکشن اور تعمیر کے وقت بائٹ کوڈ تبدیلی کے لیے Gradle Transform API / ASM۔

kotlin
// Android پر ریفلیکشن + companion object کے ذریعے Swizzling
class Logger {
    companion object {
        var originalImpl: (() -> Unit)? = null
    }

    fun log() {
        println("اصل لاگ")
    }
}

// ریفلیکشن کے ذریعے رن ٹائم پر نفاذ کی تبدیلی
fun swizzleLog() {
    val originalMethod = Logger::class.java
        .getDeclaredMethod("log")
    originalMethod.isAccessible = true

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

    // ان لائن فنکشن کے ذریعے تبدیلی
    println("swizzled: لاگ روک لیا گیا")
}

یہ کوڈ Java ریفلیکشن کے ذریعے log() طریقہ کے رویے کو بدلتا ہے: getDeclaredMethod نجی نفاذ تک رسائی حاصل کرتا ہے، isAccessible رسائی کی جانچ کو غیر فعال کرتا ہے۔ براہ راست log() کال کرنے کے بجائے، ایک ریپر کال کیا جاتا ہے جو اضافی منطق چلاتا ہے۔ تاہم، Android JIT کے ذریعے گرم طریقوں کو بہتر بناتا ہے — ریفلیکشن پہلے سے مرتب کردہ AOT حصوں پر کام نہیں کر سکتا۔

ایک زیادہ قابل اعتماد طریقہ ASM لائبریری کے ساتھ Gradle Transform API یا AGP (Android Gradle Plugin) کے ذریعے بائٹ کوڈ ہیرا پھیری ہے۔ بائٹ کوڈ کی تبدیلی تعمیر کے وقت کی جاتی ہے: ASM کلاس کے ہر طریقہ میں کالز شامل کرتا ہے۔ کوڈ کوریج ٹولز (JaCoCo) اور کارکردگی کی نگرانی کے ٹولز (Firebase Performance Monitoring) اس طرح کام کرتے ہیں۔

Method Swizzling کے خطرات اور بہترین طرز عمل

Method Swizzling ایک اعلی خطرے والی تکنیک ہے۔ لائبریریوں کے درمیان تنازعات: اگر دو لائبریریاں ایک ہی طریقہ کو swizzle کرتی ہیں، تو عملدرآمد کی ترتیب کی ضمانت نہیں ہے۔ iOS اپ ڈیٹس کے ساتھ عدم مطابقت: اگر Apple کسی نئے iOS ورژن میں دستخط تبدیل کرے یا طریقہ ہٹائے، تو swizzling کریش کا سبب بنتا ہے۔ کوڈ میں مرئیت کی کمی: swizzling کلاس کے نفاذ میں نظر نہیں آتا، جس سے ڈیبگنگ مشکل ہو جاتی ہے۔

خطرہتفصیلکم کرنا
لائبریری تنازعدو لائبریریاں viewDidAppear کو swizzle کرتی ہیں — ایک دوسری کو توڑ دیتی ہےclass_getInstanceMethod کے ذریعے چیک کریں کہ طریقہ پہلے سے swizzled ہے یا نہیں
تکراراسی طریقہ کو دوبارہ swizzle کرنے سے لامحدود لوپ ہوتا ہےہمیشہ dispatch_once استعمال کریں
دستخط کی تبدیلیApple نئے iOS میں طریقہ کا دستخط تبدیل کرتا ہے — IMP مماثلت نہیںتمام معاون iOS ورژنز پر ٹیسٹ کریں
غیر مرئیSwizzling Xcode کال اسٹیک میں ظاہر نہیں ہوتاکوڈ میں تمام swizzling کارروائیوں کو دستاویز کریں
App ReviewApple غیر دستاویزی swizzling والی ایپلیکیشنز کو مسترد کرتا ہےصرف عوامی APIs استعمال کریں اور مقصد کو دستاویز کریں

محفوظ swizzling کے لیے بہترین طرز عمل میں شامل ہیں: ہمیشہ اصل نفاذ کو کال کریں، dispatch_once کے ذریعے +load میں سختی سے swizzling کریں، swizzled طریقوں کو سابقہ (مثلاً s_originalMethodName) کے ساتھ نام دیں، ہر swizzling کارروائی کو اس کے مقصد کے ساتھ دستاویز کریں۔ Aspects لائبریری اصل طریقہ سے پہلے/بعد بلاکس کی زنجیری عملدرآمد کے ذریعے تنازع کے مسئلے کو حل کرتی ہے۔

جدید ڈیولپمنٹ میں Method Swizzling کے متبادل

Method swizzling کے متبادل پیش قیاسی اور حفاظت کی وجہ سے پروڈکشن کوڈ کے لیے ترجیحی ہیں۔ ڈیلیگیٹ اور پروٹوکول (UIApplicationDelegate, UITableViewDelegate) رن ٹائم کو تبدیل کیے بغیر واضح توسیعی نکات فراہم کرتے ہیں۔ ذیلی کلاس بنانا — viewDidAppear کو اوور رائڈ کرنے والا UIViewController کا ذیلی کلاس بنانا — پیش قیاسی طور پر کام کرتا ہے اور اس میں کوئی تنازع نہیں ہے۔

SwiftUI اور Combine swizzling کی ضرورت کو ختم کرتے ہیں: موڈیفائر (onAppear, onChange) طریقوں کو اوور رائڈ کیے بغیر اعلانیہ طور پر رویہ شامل کرتے ہیں۔ Android Jetpack Compose میں اثرات (LaunchedEffect, SideEffect) اور موڈیفائر کے ذریعے وہی حاصل کیا جاتا ہے۔ AOP فریم ورک (Android کے لیے AspectJ، iOS کے لیے InterposeKit) تعمیراتی وقت کی weaving کے ساتھ ایک محفوظ متبادل فراہم کرتے ہیں۔

Apple WWDC 2024 کے اعداد و شمار کے مطابق، Swift رن ٹائم زبان کی سطح پر method swizzling کی حمایت نہیں کرتا — @objc dynamic طریقوں کو صرف Objective-C Runtime کے ذریعے swizzle کیا جا سکتا ہے۔ جو Swift ایپلیکیشنز @objc استعمال نہیں کرتیں، وہ تیسرے فریق کی لائبریریوں کے ذریعے حادثاتی swizzling سے مکمل طور پر محفوظ ہیں۔ یہ Swift کو زیادہ محفوظ بناتا ہے لیکن رن ٹائم آلات سازی کی صلاحیتوں کو محدود کرتا ہے۔

SwiftUI اور Compose میں اعلانیہ متبادل

SwiftUI موڈیفائر (onAppear, onChange, onReceive) اور Jetpack Compose اثرات (LaunchedEffect, SideEffect, DisposableEffect) UI کاموں کے لیے swizzling کو مکمل طور پر بدل دیتے ہیں۔ وہ ڈسپیچ ٹیبل کو تبدیل کیے بغیر کراس کٹنگ رویہ شامل کرنے کا ایک اعلانیہ، پیش قیاسی اور قابل جانچ طریقہ فراہم کرتے ہیں۔ نئے پروجیکٹس میں، Apple اور Google رن ٹائم مداخلت کے بجائے اس طریقہ کار کی سفارش کرتے ہیں۔

اکثر پوچھے گئے سوالات

کیا Method Swizzling پروڈکشن کے لیے محفوظ ہے؟

Method Swizzling پروڈکشن کے لیے قابل قبول ہے جب اصولوں پر عمل کیا جائے: ایک بار عملدرآمد کے لیے dispatch_once، اصل نفاذ کو کال کرنا، تمام iOS ورژنز پر ٹیسٹنگ اور دستاویز کاری۔ سادہ کاموں کے لیے، ڈیلیگیٹ یا ذیلی کلاس بنانا بہتر ہے۔ پروڈکشن میں Swizzling مانیٹرنگ اور اینالیٹکس لائبریریوں کے لیے جائز ہے۔

Swizzling AOP سے کیسے مختلف ہے؟

Method Swizzling ڈسپیچ ٹیبل میں IMPs کو تبدیل کرنے کی ایک مخصوص تکنیک ہے۔ AOP (پہلو پر مبنی پروگرامنگ) ایک نمونہ ہے جس میں swizzling کو ایک میکانزم کے طور پر استعمال کیا جا سکتا ہے۔ AOP میں تعمیراتی وقت کی weaving (AspectJ)، پراکسی پر مبنی مداخلت (Spring AOP) اور کوڈ جنریشن بھی شامل ہے۔

Swizzling کی وجہ سے ہونے والے مسائل کو کیسے ڈیبگ کریں؟

تمام پیغامات کو ٹریک کرنے کے لیے objc_msgSend میں بریک پوائنٹ استعمال کریں۔ کلاس کے نام پر شرط کے ساتھ method_exchangeImplementations پر علامتی بریک پوائنٹ شامل کریں۔ FLEX ٹول دکھاتا ہے کہ کلاس کے کون سے طریقے swizzled ہیں۔ منظم جانچ کے لیے، lldb اسکرپٹ استعمال کریں جو کلاس کا ڈسپیچ ٹیبل آؤٹ پٹ کرے۔

کیا Swizzling Swift میں کام کرتا ہے؟

Swift زبان کی سطح پر swizzling کی حمایت نہیں کرتا۔ Method Swizzling صرف @objc dynamic سے نشان زد طریقوں کے لیے کام کرتا ہے، جو Objective-C Runtime کے ذریعے مرتب ہوتے ہیں۔ خالص Swift طریقے (بغیر @objc کے) جامد تقسیم استعمال کرتے ہیں اور swizzle نہیں کیے جا سکتے — ان کا ڈسپیچ ٹیبل تبدیلی کے لیے قابل رسائی نہیں ہے۔

کون سی iOS لائبریریاں Swizzling استعمال کرتی ہیں؟

Firebase Analytics (خودکار اسکرین ٹریکنگ کے لیے viewDidAppear کا swizzling)، Amplitude، Mixpanel، FLEX (UI معائنہ)، OHHTTPStubs (نیٹ ورک درخواستوں کی نقل)، Aspects (AOP فریم ورک)۔ یہ سب اصل نفاذ کو کال کرتے ہوئے dispatch_once کے ذریعے +load میں swizzling کرتی ہیں۔

خلاصہ

  • Method Swizzling — method_exchangeImplementations کے ذریعے Objective-C Runtime ڈسپیچ ٹیبل میں دو طریقوں کے IMPs کا تبادلہ۔
  • dispatch_once دوبارہ swizzling اور تکرار کو روکنے کے لیے لازمی ہے۔
  • اصل نفاذ کو کال کرنا swizzled طریقہ کے اندر ایک لازمی حفاظتی اصول ہے۔
  • Android پر، swizzling کو Gradle Transform / ASM کے ذریعے ریفلیکشن یا بائٹ کوڈ ہیرا پھیری سے بدل دیا جاتا ہے۔
  • خطرات — لائبریری تنازعات، iOS ورژنز کے ساتھ عدم مطابقت، ڈیبگر میں غیر مرئی اور ہاٹ فکسز کے لیے App Review پابندی۔
  • متبادل — ڈیلیگیٹ، ذیلی کلاس بنانا، SwiftUI موڈیفائر، Jetpack Compose اثرات۔
  • @objc dynamic کے بغیر Swift طریقے swizzling سے محفوظ ہیں، جو استحکام کو بہتر بناتا ہے لیکن رن ٹائم آلات سازی کو محدود کرتا ہے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں