Objective-C ایک پروگرامنگ زبان ہے جس میں متحرک پیغام کی ترسیل ہے، جسے بریڈ کاکس نے 1980 کی دہائی میں بنایا۔ Apple نے NeXTSTEP کے لیے اور بعد میں iOS SDK کے لیے Objective-C کو بنیادی زبان کے طور پر چنا۔ Programming With Objective-C — پیغام کی نحویت اور میموری کے انتظام کا تعارف۔
بنیادی نکات
Objective-C ایک پروگرامنگ زبان ہے جو C کو Smalltalk کے انداز میں آبجیکٹ اورینٹڈ پروگرامنگ کی صلاحیتوں سے وسعت دیتی ہے۔ Objective-C کوڈ LLVM یا GCC کے ذریعے مقامی مشین کوڈ میں مرتب ہوتا ہے، C کے ساتھ مکمل پسماندہ مطابقت برقرار رکھتا ہے — کوئی بھی C کوڈ Objective-C میں درست ہے۔
Apple نے 1997 میں NeXT (Objective-C کے ساتھ) حاصل کیا۔ یہ زبان Cocoa اور Cocoa Touch — macOS اور iOS کے فریم ورکس کی بنیاد بن گئی۔ 2014 سے، Apple Swift کو متبادل کے طور پر فروغ دے رہا ہے، لیکن Objective-C میراثی منصوبوں اور کچھ نظامی فریم ورکس کے لیے انتہائی اہم ہے۔ Apple (WWDC 2024) کے مطابق، App Store میں تقریباً 35% ایپس میں اب بھی Objective-C کوڈ موجود ہے۔
اہم خصوصیت متحرک رن ٹائم ہے۔ Swift کے برعکس، جہاں طریقہ کالز مرتب وقت پر حل ہوتی ہیں، Objective-C objc_msgSend فنکشن کے ذریعے رن ٹائم پر پیغامات بھیجتا ہے۔ یہ طریقوں کو فوری طور پر اوور رائڈ کرنے (method swizzling)، متحرک طور پر کلاسز شامل کرنے اور غیر موجود سلیکٹرز کے لیے forward invocation استعمال کرنے کی اجازت دیتا ہے۔
کوئی بھی C کوڈ Objective-C میں درست ہے۔ آبجیکٹ اورینٹڈ توسیع کلاسز (@interface/@implementation)، زمرہ جات، پروٹوکول (@protocol) اور متحرک ٹائپنگ (id) شامل کرتی ہے۔ فائلوں میں .m (نفاذ) اور .h (ہیڈر) کی توسیعات ہوتی ہیں۔
پیغام کی نحویت Objective-C اور C جیسی زبانوں کے درمیان بنیادی فرق ہے۔ object.method(argument) کے بجائے [object method:argument] استعمال ہوتا ہے۔ ہر پیغام objc_msgSend سے گزرتا ہے، جو رن ٹائم میں متحرک طور پر طریقہ کے نفاذ کو تلاش کرتا ہے۔
// نامزد پیرامیٹرز کے ساتھ پیغام کی نحویت
NSString *greeting = [NSString stringWithFormat:@"Hello, %@", name];
// مرتب پیغامات
NSArray *sortedArray = [[array sortedArrayUsingSelector:@selector(compare:)] copy];
// introspection کے ذریعے قسم کی جانچ
if ([object isKindOfClass:[UIView class]]) {
UIView *view = (UIView *)object;
view.backgroundColor = [UIColor redColor];
}متحرک ترسیل رن ٹائم پر طریقوں کو اوور رائڈ کرنے (method swizzling) کی اجازت دیتی ہے — ایک طاقتور لیکن خطرناک تکنیک۔ مثال کے طور پر، AFNetworking اور Aspects جیسے فریم ورک URLSession کالز کو روکنے کے لیے swizzling استعمال کرتے ہیں۔ Apple خبردار کرتا ہے: غلط استعمال پر swizzling نظامی فریم ورکس کو توڑ سکتا ہے۔
زمرہ جات Objective-C کی ایک منفرد خصوصیت ہے جو موجودہ کلاسز (NSString اور UIView جیسی نظامی کلاسز سمیت) میں وراثت اور سورس کوڈ تک رسائی کے بغیر طریقے شامل کرنے کی اجازت دیتی ہے۔ زمرہ جات @interface ClassName (CategoryName) کے ذریعے اعلان کیے جاتے ہیں۔
// UIColor+Hex.h فائل — UIColor کے لیے زمرہ
@interface UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex;
@end
// UIColor+Hex.m فائل — نفاذ
@implementation UIColor (Hex)
+ (instancetype)colorWithHex:NSUIntegerhex {
CGFloat r = ((hex >> 16) & 0xFF) / 255.0;
CGFloat g = ((hex >> 8) & 0xFF) / 255.0;
CGFloat b = (hex & 0xFF) / 255.0;
return [self colorWithRed:r green:g blue:b alpha:1.0];
}
@endتوسیعات (Class Extension) ایک خاص قسم کا زمرہ ہے جو .m فائل میں بغیر نام کے اعلان کیا جاتا ہے: @interface ClassName ()۔ زمرہ جات کے برعکس، توسیعات نہ صرف طریقے بلکہ ivar (مثال متغیرات) اور خصوصیات بھی شامل کر سکتی ہیں۔ توسیعات بیرونی ماڈیولز سے اندرونی API کو چھپانے کے لیے استعمال ہوتی ہیں۔
بلاکس Objective-C میں گمنام افعال ہیں جو بیرونی دائرہ کار سے متغیرات کو پکڑتے ہیں۔ بلاک نحویت: ^(int x) { return x * 2; }۔ بلاکس UIKit میں کال بیک ہینڈلرز کے لیے، Grand Central Dispatch میں غیر متزامن کاموں کے لیے اور NSArray/NSDictionary مجموعات میں فعلیاتی کارروائیوں کے لیے استعمال ہوتے ہیں۔
// بلاک قسم کا اعلان
typedef void (^CompletionBlock)(BOOL success, NSError *error);
// پیرامیٹر کے طور پر بلاک
- (void)fetchDataWithCompletion:(CompletionBlock)completion {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL result = [weakSelf processData];
if (completion) {
completion(result, nil);
}
});
}بلاکس میں میموری کا انتظام انتہائی اہم ہے۔ بلاکس self کو مضبوط حوالے سے پکڑتے ہیں، جو براہ راست استعمال پر retain cycle بناتا ہے۔ حل ہے __weak typeof(self) weakSelf = self، اس کے بعد بلاک کے اندر جانچ۔ یہ مسئلہ Swift میں capture lists [weak self] کے ذریعے مکمل طور پر حل ہو گیا ہے۔
Objective-C MRC (Manual Reference Counting) سے ARC (Automatic Reference Counting) تک ترقی پائی۔ MRC میں، ڈیولپر دستی طور پر retain (گنتی بڑھانا)، release (گھٹانا) اور autorelease (مؤخر رہائی) کال کرتا تھا۔ ان کالز میں غلطیاں میموری لیک یا لٹکتے پوائنٹرز کی وجہ سے کریش کا سبب بنتی تھیں۔
| عمل | MRC | ARC |
|---|---|---|
| آبجیکٹ بنانا | [[Object alloc] init] | [[Object alloc] init] |
| حوالہ رکھنا | [object retain] | خودکار |
| رہائی | [object release] | خودکار |
| خودکار رہائی | [object autorelease] | خودکار (ضروری نہیں) |
| کمزور حوالہ | __weak موجود نہ تھا | __weak (خودکار nil) |
ARC Xcode 4.2 اور LLVM 3.0 (2011) میں متعارف کرایا گیا۔ مرتب کنندہ آبجیکٹ کی عمر کا تجزیہ کرکے مرتب وقت پر خود بخود retain/release داخل کرتا ہے۔ ARC کچرا جمع کرنا (GC) نہیں ہے — یہ خودکار اندراج کے ساتھ جامد تجزیہ ہے۔ Objective-C ARC، Swift ARC کے ساتھ مطابقت رکھتا ہے: دونوں رن ٹائم سطح پر ایک ہی حوالہ گنتی نظام استعمال کرتے ہیں۔
ایک منصوبے میں Objective-C اور Swift کا مشترکہ استعمال میراثی منصوبوں کے لیے عام عمل ہے۔ Apple Bridging Header فراہم کرتا ہے — ایک خودکار طور پر تیار کردہ فائل جس کے ذریعے Swift Objective-C کلاسز دیکھتا ہے، اور Objective-C NSObject سے ماخوذ Swift کلاسز دیکھتا ہے۔
// ProjectName-Bridging-Header.h
// Swift ان ہیڈرز کو خود بخود دیکھتا ہے
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"Objective-C سے Swift میں منتقلی ایک تدریجی عمل ہے۔ نئی فائلیں Swift میں لکھی جاتی ہیں، پرانی آہستہ آہستہ ری فیکٹر کی جاتی ہیں۔ Bridging Header خود بخود تیار ہوتا ہے جب Objective-C منصوبے میں پہلی Swift فائل شامل کی جاتی ہے۔ الٹی مرئیت (ObjC → Swift) کے لیے، Xcode ایک <ProjectName>-Swift.h فائل تیار کرتا ہے جس میں @objc سے نشان زد Swift کلاسز کے @interface اعلانات ہوتے ہیں۔
// Objective-C سے نظر آنے والی Swift کلاس
@objc class SwiftRouter: NSObject {
@objc func navigateToProfile(userId: Int) {
// نفاذ
}
}حدود: Swift کی قدر کی اقسام (struct, enum) Objective-C سے براہ راست نظر نہیں آتیں — انہیں @objc کے ساتھ کلاس میں لپیٹنا ضروری ہے۔ Swift کے جنرکس Objective-C سے محدود رسائی رکھتے ہیں۔ تجویز کردہ طریقہ یہ ہے کہ نیا کوڈ Swift میں لکھیں اور موجودہ Objective-C کوڈ کو صرف متعلقہ فعالیت تبدیل کرتے وقت ری فیکٹر کریں۔
Swift پر Objective-C کا بنیادی فائدہ رن ٹائم تک مکمل رسائی ہے۔ Method swizzling، رن ٹائم پر طریقہ کے نفاذ کو تبدیل کرنا، وراثت کے بغیر نظامی طریقوں کو اوور رائڈ کرنے کی اجازت دیتا ہے۔ Aspects اور JRSwizzle جیسی لائبریریاں AOP (پہلو پر مبنی پروگرامنگ) — نگرانی، تجزیہ اور لاگنگ کے لیے یہ صلاحیت استعمال کرتی ہیں۔
Forward invocation ایک اور رن ٹائم خصوصیت ہے: اگر کوئی آبجیکٹ سلیکٹر کا جواب نہیں دیتا، نظام forwardInvocation: کال کرتا ہے، جس سے پیغام کو دوسرے آبجیکٹ کو بھیجنے کی اجازت ملتی ہے۔ یہ Objective-C (NSProxy) میں پراکسی پیٹرن کی بنیاد ہے، جو سست ابتدائیہ اور تقسیم شدہ آبجیکٹس کے لیے استعمال ہوتا ہے۔
Apple نئے کوڈ میں رن ٹائم چالوں کے استعمال کو کم سے کم کرنے، Swift کی جامد ٹائپنگ کو ترجیح دینے کی سفارش کرتا ہے۔ تاہم، میراثی منصوبوں میں، objc_msgSend، method_exchangeImplementations اور objc_getAssociatedObject کا علم موجودہ کوڈ بیس کی دیکھ بھال کے لیے ضروری ہے۔
Objective-C getter/setter کے ساتھ ivar پر خصوصیات کو نحوی شکر کے طور پر سپورٹ کرتا ہے۔ atomic/nonatomic، strong/weak/copy، readonly/readwrite اور assign/retain میں ترمیم کنندگان میموری کے رویے اور تھریڈ کی حفاظت کا تعین کرتے ہیں۔ Key-Value Observing (KVO) رن ٹائم میں شامل خصوصیت کی تبدیلی کے مشاہدے کا ایک طریقہ کار ہے: کوئی بھی آبجیکٹ addObserver کے ذریعے دوسرے آبجیکٹ کی خصوصیات میں تبدیلیوں کو سبسکرائب کر سکتا ہے۔
اکثر پوچھے گئے سوالات
طریقہ کال [object selector:argument] جیسی نظر آتی ہے۔ پیغام objc_msgSend سے گزرتا ہے، جو رن ٹائم میں متحرک طور پر نفاذ تلاش کرتا ہے۔ سلیکٹر ایک طریقہ کا نام ہے (@selector(methodName))، فنکشن پوائنٹر نہیں۔ یہ swizzling اور forward invocation کو قابل بناتا ہے۔
زمرہ (@interface ClassName (Name)) وراثت کے بغیر کسی بھی کلاس (نظامی کلاسز سمیت) میں طریقے شامل کرتا ہے۔ توسیع (@interface ClassName ()) .m فائل میں اعلان کی جاتی ہے اور خصوصیات اور ivars شامل کر سکتی ہے۔ زمرہ ivars شامل نہیں کر سکتا، لیکن توسیع کر سکتی ہے۔
بلاکس ^(پیرامیٹرز) { باڈی } نحویت کے ساتھ گمنام افعال ہیں، جو سیاق و سباق سے متغیرات پکڑتے ہیں۔ یہ C++ میں لیمبڈا اور Swift میں بندشوں سے مشابہ ہیں۔ self پکڑتے وقت retain cycles روکنے کے لیے __weak کی ضرورت ہوتی ہے۔ UIKit، GCD اور Foundation میں استعمال ہوتے ہیں۔
MRC دستی حوالہ گنتی ہے: پروگرامر retain، release، autorelease کال کرتا ہے۔ ARC خودکار ہے: مرتب کنندہ جامد تجزیہ کی بنیاد پر retain/release داخل کرتا ہے۔ ARC GC نہیں ہے — گنتی صفر ہونے پر آبجیکٹ فوری طور پر رہا ہو جاتے ہیں۔ ARC __weak اور __strong میں ترمیم کنندگان کو سپورٹ کرتا ہے۔
ہاں، Bridging Header کے ذریعے۔ Swift اس ہیڈر کے ذریعے Objective-C دیکھتا ہے، Objective-C <ProjectName>-Swift.h کے ذریعے Swift دیکھتا ہے۔ Swift کلاسز کو NSObject سے ماخوذ اور @objc سے نشان زد ہونا چاہیے۔ Swift کے struct اور enum Objective-C کو براہ راست نظر نہیں آتے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔