Objective-C هي لغة برمجة مع إرسال ديناميكي للرسائل، أنشأها براد كوكس في الثمانينيات. اختارت Apple لغة Objective-C كلغة رئيسية لـ NeXTSTEP، ثم لاحقًا لـ iOS SDK. Programming With Objective-C — مقدمة إلى صيغة الرسائل وإدارة الذاكرة.
الخلاصة
Objective-C هي لغة برمجة توسع C بإمكانيات البرمجة كائنية التوجه بأسلوب Smalltalk. يتم تجميع كود Objective-C عبر LLVM أو GCC إلى كود آلة أصلي، مع الحفاظ على التوافق العكسي الكامل مع C — أي كود C صحيح في Objective-C.
استحوذت Apple على NeXT (جنبًا إلى جنب مع Objective-C) في عام 1997. أصبحت اللغة أساس Cocoa وCocoa Touch — أطر العمل لنظامي macOS وiOS. منذ عام 2014، تروج Apple لـ Swift كبديل، لكن Objective-C لا تزال مهمة بشكل حاسم للمشاريع القديمة وبعض أطر العمل النظامية. وفقًا لـ Apple (WWDC 2024)، حوالي 35% من التطبيقات في App Store لا تزال تحتوي على كود 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 تستخدم swizzling لاعتراض استدعاءات URLSession. تحذر Apple: swizzling قد يعطل أطر العمل النظامية إذا استخدم بشكل غير صحيح.
التصنيفات (Categories) هي ميزة فريدة في 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الامتدادات (Extensions) هي نوع خاص من التصنيفات يُعلن في ملف .m بدون اسم: @interface ClassName (). على عكس التصنيفات، يمكن للامتدادات إضافة ليس فقط الدوال ولكن أيضًا ivar (متغيرات المثيل) والخصائص. تُستخدم الامتدادات لإخفاء API الداخلي عن الوحدات الخارجية.
الكتل (Blocks) هي دوال مجهولة في 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 ليس جمعًا للقمامة — إنه تحليل ثابت مع إدراجات تلقائية. ARC في Objective-C متوافق مع ARC في Swift: كلاهما يستخدم نفس نظام عد المراجع على مستوى بيئة التشغيل.
الاستخدام المشترك لـ Objective-C وSwift في مشروع واحد هو ممارسة شائعة للمشاريع القديمة. توفر Apple Bridging Header — ملف يتم إنشاؤه تلقائيًا ترى من خلاله Swift فئات Objective-C، ويرى Objective-C فئات Swift التي ترث من NSObject.
// ProjectName-Bridging-Header.h
// Swift يرى هذه الرؤوس تلقائيًا
#import "LegacyManager.h"
#import "NetworkClient.h"
#import "DataStore.h"الترحيل من Objective-C إلى Swift هو عملية تدريجية. تُكتب الملفات الجديدة بلغة Swift، وتُعيد هيكلة القديمة تدريجيًا. يتم إنشاء Bridging Header تلقائيًا عند إضافة أول ملف Swift إلى مشروع Objective-C. للرؤية العكسية (ObjC ← Swift)، ينشئ Xcode ملف <ProjectName>-Swift.h يحتوي على تعريفات @interface لفئات Swift المميزة بـ @objc.
// فئة Swift مرئية من Objective-C
@objc class SwiftRouter: NSObject {
@objc func navigateToProfile(userId: Int) {
// تنفيذ
}
}القيود: أنواع القيم في Swift (struct, enum) غير مرئية مباشرة من Objective-C — يجب تغليفها في فئة مع @objc. الأدوية العامة (generics) في Swift ذات وصول محدود من Objective-C. النهج الموصى به هو كتابة كود جديد بلغة Swift وإعادة هيكلة كود Objective-C الموجود فقط عند تغيير الوظيفة المقابلة.
الميزة الرئيسية لـ Objective-C على Swift هي الوصول الكامل إلى بيئة التشغيل. Method swizzling، استبدال تنفيذ الدوال في وقت التشغيل، يسمح بتجاوز دوال النظام دون وراثة. تستخدم المكتبات مثل Aspects وJRSwizzle هذه الإمكانية لـ AOP (البرمجة الموجهة بالجوانب) — المراقبة والتحليل والتسجيل.
Forward invocation هي ميزة أخرى لبيئة التشغيل: إذا لم يستجب كائن لمحدد، يستدعي النظام forwardInvocation:، مما يسمح بإعادة توجيه الرسالة إلى كائن آخر. هذا هو أساس نمط Proxy في Objective-C (NSProxy)، المستخدم للتهيئة البطيئة والكائنات الموزعة.
توصي Apple بتقليل استخدام حيل بيئة التشغيل في الكود الجديد، مفضلة الكتابة الثابتة لـ Swift. ومع ذلك، في المشاريع القديمة، معرفة objc_msgSend وmethod_exchangeImplementations وobjc_getAssociatedObject ضرورية لصيانة قاعدة الكود الموجودة.
تدعم Objective-C الخصائص كسكر تركيب فوق ivar مع getters/setters. تحدد معدّلات atomic/nonatomic وstrong/weak/copy وreadonly/readwrite وassign/retain سلوك الذاكرة وأمان الخيوط. Key-Value Observing (KVO) هي آلية لمراقبة تغييرات الخصائص، مدمجة في بيئة التشغيل: يمكن لأي كائن الاشتراك في تغييرات خصائص كائن آخر عبر addObserver.
الأسئلة الشائعة
استدعاء الدالة يبدو كـ [object selector:argument]. تمر الرسالة عبر objc_msgSend، الذي يجد ديناميكيًا التنفيذ في بيئة التشغيل. المحدد (selector) هو اسم الدالة (@selector(methodName))، وليس مؤشرًا لدالة. يتيح ذلك swizzling وforward invocation.
التصنيف (@interface ClassName (Name)) يضيف دوال إلى أي فئة (بما في ذلك فئات النظام) دون وراثة. الامتداد (@interface ClassName ()) يُعلن في ملف .m ويمكنه إضافة خصائص وivars. التصنيف لا يمكنه إضافة ivars، لكن الامتداد يمكنه.
الكتل هي دوال مجهولة بصيغة ^(معاملات) { جسم }، تلتقط المتغيرات من السياق. تماثل lambdas في C++ وclosures في Swift. تتطلب __weak لمنع retain cycles عند التقاط self. تُستخدم في UIKit وGCD وFoundation.
MRC هو عد يدوي للمراجع: المبرمج يستدعي retain وrelease وautorelease. ARC تلقائي: المترجم يدرج retain/release بناءً على تحليل ثابت. ARC ليس GC — يتم تحرير الكائنات فورًا عند وصول العداد إلى الصفر. ARC يدعم معدّلات __weak و__strong.
نعم، عبر Bridging Header. ترى Swift Objective-C من خلال هذا الرأس، ويرى Objective-C Swift عبر <ProjectName>-Swift.h. يجب أن ترث فئات Swift من NSObject وتكون مميزة بـ @objc. Struct وenum في Swift غير مرئية مباشرة لـ Objective-C.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.