Objective-C একটি প্রোগ্রামিং ভাষা যা ডায়নামিক মেসেজ ডিসপ্যাচ সমর্থন করে, ১৯৮০-এর দশকে ব্র্যাড কক্স তৈরি করেছিলেন। Apple NeXTSTEP-এর জন্য এবং পরে iOS SDK-এর জন্য Objective-C-কে প্রধান ভাষা হিসেবে বেছে নেয়। Programming With Objective-C — মেসেজ সিনট্যাক্স এবং মেমোরি ব্যবস্থাপনার ভূমিকা।
মূল বিষয়
Objective-C একটি প্রোগ্রামিং ভাষা যা C-কে Smalltalk শৈলীতে অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ক্ষমতা দিয়ে সম্প্রসারিত করে। Objective-C কোড LLVM বা GCC-এর মাধ্যমে নেটিভ মেশিন কোডে কম্পাইল হয়, C-এর সাথে সম্পূর্ণ বিপরীত সামঞ্জস্য বজায় রাখে — যেকোনো C কোড Objective-C-তে বৈধ।
Apple ১৯৯৭ সালে NeXT (Objective-C-সহ) অধিগ্রহণ করে। ভাষাটি Cocoa এবং Cocoa Touch — macOS এবং iOS-এর ফ্রেমওয়ার্কের ভিত্তি হয়ে ওঠে। ২০১৪ সাল থেকে, Apple Swift-কে প্রতিস্থাপন হিসেবে প্রচার করছে, কিন্তু Objective-C লিগ্যাসি প্রকল্প এবং কিছু সিস্টেম ফ্রেমওয়ার্কের জন্য গুরুত্বপূর্ণ রয়ে গেছে। Apple-এর (WWDC 2024) মতে, 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];
// ইন্ট্রোস্পেকশনের মাধ্যমে টাইপ যাচাই
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/receive সন্নিবেশ করে। 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-এ লেখা হয়, পুরোনোগুলি ধীরে ধীরে রিফ্যাক্টর করা হয়। Objective-C প্রকল্পে প্রথম Swift ফাইল যোগ করলে Bridging Header স্বয়ংক্রিয়ভাবে উৎপন্ন হয়। বিপরীত দৃশ্যমানতার জন্য (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 গেটার/সেটার সহ 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।