Objective-C Runtime (অবজেক্টিভ-সি রানটাইম) হল সেই সিস্টেম, যা কোড এক্সিকিউশনের সময় অবজেক্ট, ক্লাস, মেথড, প্রোপার্টি, এবং অন্যান্য বৈশিষ্ট্যগুলির জন্য ডাইনামিক (runtime) তথ্য এবং ব্যবস্থাপনা প্রদান করে। এটি Objective-C ভাষার ডাইনামিক স্বভাবের মূল কেন্দ্র, কারণ এটি কোডের অনেক কার্যাবলী রানটাইমে সম্পাদন করে, যেমন মেথড ডিসপ্যাচ, অবজেক্ট প্রোপার্টি অ্যাক্সেস, এবং ক্লাস সম্পর্কিত তথ্য পরিচালনা।
Objective-C Runtime এর বৈশিষ্ট্য
Objective-C তে রানটাইম সিস্টেম কোডের কার্যকলাপ ডাইনামিকভাবে পরিচালনা করার সুযোগ দেয়। এই সিস্টেমের মাধ্যমে, ক্লাসের অবজেক্টের গঠন, মেথড কল, এবং ইন্টারঅ্যাকশনগুলির মধ্যে পরিবর্তন করা যায়, যা স্ট্যাটিক (compile-time) সময়ে সম্ভব নয়। Runtime এ বিভিন্ন কার্যাবলী সম্পাদিত হয়, যেমন:
- মেথড ডিসপ্যাচ
- অবজেক্টের প্রোপার্টি অ্যাক্সেস
- ক্লাসের সাথে ডাইনামিক ইন্টারঅ্যাকশন
এটি Objective-C কে আরও শক্তিশালী এবং নমনীয় করে তোলে, যেখানে কোডের অনেক কাজ রানটাইমে সম্পাদন করা হয়।
Objective-C Runtime এর কিছু প্রধান কনসেপ্ট
১. ডাইনামিক মেথড ডিসপ্যাচ (Dynamic Method Dispatch)
Objective-C তে মেথড কল করার সময়, এটি ডাইনামিক্যালি ঠিক করা হয় (রানটাইমে)। অর্থাৎ, কম্পাইলেশন সময় মেথডের ঠিকানা নির্ধারণ না হয়ে, রuntime সময়ে মেথড ডিসপ্যাচ করা হয়। এটি message passing এর মাধ্যমে কাজ করে, যেখানে একটি অবজেক্ট অন্য একটি অবজেক্টে মেসেজ পাঠিয়ে ফাংশন কল করে।
উদাহরণ:
// Example of dynamic method dispatch
[myObject someMethod];এখানে someMethod মেথডটির ঠিকানা রানটাইমে নির্ধারণ করা হয়, অর্থাৎ অবজেক্টটি কোন ক্লাসের অন্তর্গত তা চেক করার পর মেথডটি কল হয়।
২. objc_msgSend ফাংশন
Objective-C এর মেথড ডিসপ্যাচ মূলত objc_msgSend ফাংশনের মাধ্যমে করা হয়, যা মেসেজ পাঠানোর জন্য ব্যবহৃত হয়। যখন আপনি কোনো অবজেক্টে মেথড কল করেন, এটি আসলে objc_msgSend ফাংশনকে কল করে। এটি ডাইনামিকভাবে অবজেক্টের মেথড টেবিল (method table) থেকে মেথডের ঠিকানা খুঁজে বের করে।
৩. NSObject ক্লাস এবং রানটাইম
NSObject হল Objective-C এর মূল সুপার ক্লাস, যা সব ক্লাসের জন্য কিছু ডিফল্ট বৈশিষ্ট্য এবং মেথড সরবরাহ করে। এর মধ্যে কিছু গুরুত্বপূর্ণ রানটাইম সম্পর্কিত মেথড রয়েছে, যেমন:
performSelector:: এটি একটি মেথড কল করতে ব্যবহৃত হয়, তবেperformSelector:ব্যবহারের মাধ্যমে ডাইনামিক্যালি একটি মেথড চালানো সম্ভব হয়।
[myObject performSelector:@selector(someMethod)];এটি রানটাইমে মেথড নামকে কল করে এবং সেই মেথডটি চালাতে পারে।
৪. ডাইনামিক ক্লাস (Dynamic Classes)
Objective-C রানটাইমে ক্লাস তৈরি এবং পরিবর্তন করতে পারে। আপনি class_addMethod এবং class_addProperty ফাংশন ব্যবহার করে রানটাইমে নতুন মেথড বা প্রপার্টি যোগ করতে পারেন।
উদাহরণ:
#import <objc/runtime.h>
@interface MyClass : NSObject
@end
@implementation MyClass
@end
// ক্লাসে নতুন মেথড যোগ করা
void dynamicMethod(id self, SEL _cmd) {
NSLog(@"Dynamic Method called!");
}
int main() {
@autoreleasepool {
Class myClass = [MyClass class];
class_addMethod(myClass, @selector(dynamicMethod), (IMP)dynamicMethod, "v@:");
MyClass *obj = [[MyClass alloc] init];
[obj dynamicMethod]; // ডাইনামিক মেথড কল
}
return 0;
}এখানে, class_addMethod ব্যবহার করে dynamicMethod রানটাইমে MyClass ক্লাসে যোগ করা হয়েছে এবং সেই মেথডটি কল করা হয়েছে।
৫. ডাইনামিক প্রোপার্টি (Dynamic Properties)
Objective-C রানটাইমে ক্লাসের প্রপার্টি যোগ করা বা পরিবর্তন করা সম্ভব। আপনি objc_getAssociatedObject এবং objc_setAssociatedObject ব্যবহার করে কোনো অবজেক্টের সাথে প্রোপার্টি অ্যাসোসিয়েট করতে পারেন।
উদাহরণ:
#import <objc/runtime.h>
@interface MyClass : NSObject
@end
@implementation MyClass
@end
int main() {
@autoreleasepool {
MyClass *obj = [[MyClass alloc] init];
objc_setAssociatedObject(obj, @selector(dynamicProperty), @"Hello, World!", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSLog(@"%@", objc_getAssociatedObject(obj, @selector(dynamicProperty)));
}
return 0;
}এখানে, objc_setAssociatedObject এবং objc_getAssociatedObject ব্যবহার করে dynamicProperty নামে একটি ডাইনামিক প্রোপার্টি যুক্ত করা হয়েছে এবং তার মান আউটপুট করা হয়েছে।
Objective-C Runtime এর ব্যবহারিক সুবিধা
- ডাইনামিক মেথড ডিসপ্যাচ: Objective-C এর রানটাইম সিস্টেম মেথড কলের জন্য ডাইনামিক ডিসপ্যাচ ব্যবহৃত করে, যা কোডকে আরও নমনীয় করে তোলে। এটি message passing প্রযুক্তি ব্যবহার করে, যেখানে একটি অবজেক্ট অন্য অবজেক্টকে মেসেজ পাঠিয়ে কার্য সম্পাদন করে।
- ক্লাসের পরিবর্তন: রানটাইমে আপনি নতুন ক্লাস বা মেথড তৈরি করতে পারেন, যা কোডের ফ্লেক্সিবিলিটি বৃদ্ধি করে। যেমন, একটি ক্লাসে নতুন মেথড অ্যাড করা, বা রানটাইমে ক্লাস পরিবর্তন করা।
- রানটাইম প্রোপার্টি অ্যাসোসিয়েশন: আপনি
objc_getAssociatedObjectএবংobjc_setAssociatedObjectব্যবহার করে প্রোপার্টি অ্যাসোসিয়েট করতে পারেন, যা মেমরি ব্যবস্থাপনা সহজ করে।
সারাংশ
Objective-C Runtime একটি শক্তিশালী সিস্টেম যা কোডের ডাইনামিক কার্যাবলী পরিচালনা করতে সহায়তা করে। এটি message passing এর মাধ্যমে মেথড ডিসপ্যাচ এবং ক্লাস পরিবর্তনের সুযোগ দেয়, যার ফলে কোড আরও নমনীয় এবং ফ্লেক্সিবল হয়। রানটাইমের মাধ্যমে নতুন মেথড যোগ করা, ডাইনামিক প্রোপার্টি ব্যবহার করা এবং কোডে ডাইনামিক পরিবর্তন করা সম্ভব হয়, যা স্ট্যাটিক ভাষাগুলির তুলনায় Objective-C কে আরও শক্তিশালী করে তোলে।
Objective-C Runtime হলো সেই সিস্টেম যা Objective-C প্রোগ্রামিং ভাষার জন্য ডাইনামিক কার্যকলাপ পরিচালনা করে। এটি অ্যাপ্লিকেশন চালানোর সময় কোডের কার্যকারিতা নিয়ন্ত্রণ করে এবং অনেক ধরনের ডাইনামিক আচরণ যেমন মেথড কল, মেসেজ সেন্ট, প্রপার্টি এক্সেস ইত্যাদি পরিচালনা করে। Objective-C তে রUNTIME বেশ গুরুত্বপূর্ণ কারণ এটি কোডের আচরণ এবং অবজেক্টের মধ্যকার সম্পর্ক কিভাবে পরিচালিত হবে তা বাস্তব সময়ে নির্ধারণ করতে সহায়তা করে।
Objective-C Runtime এর মূল বৈশিষ্ট্যসমূহ
- ডাইনামিক টাইপিং:
Objective-C একটি ডাইনামিক টাইপিং ভাষা, যার মানে হল যে, আপনি অবজেক্টের টাইপ রানটাইমে জানেন, কম্পাইল টাইমে না। এই বৈশিষ্ট্যটি Objective-C রUNTIME এর মাধ্যমে সম্ভব হয়, যা অবজেক্টের টাইপ এবং মেথড মেলানো এবং কল করা পরিচালনা করে। - ডাইনামিক মেসেজ পাসিং:
Objective-C তে মেসেজ পাসিং একটি মৌলিক ধারণা। যখন আপনি একটি মেথড কল করেন, এটি ডাইনামিকভাবে রানটাইমে অবজেক্টের কাছে মেসেজ পাঠায়। Objective-C রUNTIME এ এই মেসেজ পাসিং সিস্টেমের মাধ্যমে মেথডের কল ডায়নামিকভাবে পরিচালনা করা হয়। - মেথড এবং প্রপার্টি সমর্থন:
রUNTIME মেথড এবং প্রপার্টি এক্সেসের জন্য ব্যবহৃত হয়। আপনি যে কোন অবজেক্টের মেথড অথবা প্রপার্টি ডাইনামিকভাবে এক্সেস করতে পারেন। এটি বিশেষ করে অনেক কোড জেনারেট করার সময় এবং কাস্টম ক্লাস ব্যবহার করার ক্ষেত্রে গুরুত্বপূর্ণ। - ক্লাস রিফ্লেকশন:
Objective-C তে রUNTIME ক্লাস রিফ্লেকশন সমর্থন করে, যার মাধ্যমে আপনি একটি অবজেক্ট বা ক্লাসের টাইপ, তার প্রপার্টি এবং মেথড সম্পর্কে তথ্য পেতে পারেন। রিফ্লেকশন বা আউটপুট যাচাই করতে রUNTIME এটি বাস্তবায়ন করে।
Runtime এর মাধ্যমে কী করা যায়?
মেথডের কল:
Objective-C তে যখন আপনি কোনো মেথড কল করেন, তখন এটি কিভাবে এবং কোথায় কল হবে তা রUNTIME দ্বারা নির্ধারিত হয়। সুতরাং, মেথড কলে ডাইনামিক আচরণ করা সম্ভব।// একটি সাধারণ মেসেজ পাসিং [object someMethod];এখানে
someMethodমেথডটি শুধুমাত্র অবজেক্টের টাইপের উপর নির্ভর করে না, রUNTIME এটি খুঁজে বের করবে এবং বাস্তবায়ন করবে।ডাইনামিক ক্লাস তৈরি এবং মেথড অ্যাড করা:
RUNTIME এর মাধ্যমে আপনি নতুন ক্লাস তৈরি করতে পারেন বা কোন ক্লাসে নতুন মেথড অ্যাড করতে পারেন। এটি খুবই শক্তিশালী, কারণ আপনি কোড রানটাইমে পরিবর্তন করতে পারেন।// ডাইনামিক ক্লাস তৈরি করা Class newClass = objc_allocateClassPair([NSObject class], "MyClass", 0); class_addMethod(newClass, @selector(newMethod), (IMP)methodImplementation, "v@:"); objc_registerClassPair(newClass);এখানে
objc_allocateClassPairএকটি নতুন ক্লাস তৈরি করছে এবংclass_addMethodএর মাধ্যমে নতুন মেথড যোগ করা হচ্ছে। এটি Objective-C রUNTIME এর ক্ষমতা এবং নমনীয়তা প্রদর্শন করে।ক্লাস এবং মেথড সম্পর্কে তথ্য পাওয়া:
রUNTIME এর মাধ্যমে আপনি একটি অবজেক্ট বা ক্লাসের সমস্ত মেথড এবং প্রপার্টি সম্পর্কে জানতে পারেন। এটি কোডের নির্দিষ্ট অংশের উপর আরো নিয়ন্ত্রণ প্রদান করে।unsigned int methodCount; Method *methods = class_copyMethodList([NSObject class], &methodCount); for (unsigned int i = 0; i < methodCount; i++) { SEL methodName = method_getName(methods[i]); NSLog(@"Method: %@", NSStringFromSelector(methodName)); }এই কোডে
class_copyMethodListব্যবহার করা হয়েছে ক্লাসের সমস্ত মেথডের তালিকা পেতে এবংmethod_getNameব্যবহার করা হয়েছে প্রতিটি মেথডের নাম প্রাপ্ত করার জন্য।
Objective-C Runtime এর গুরুত্বপূর্ণ ফাংশনসমূহ
objc_getClass: একটি ক্লাসের রেফারেন্স পাওয়ার জন্য।Class myClass = objc_getClass("MyClass");class_addMethod: একটি নতুন মেথড ক্লাসে যোগ করার জন্য।class_addMethod(myClass, @selector(newMethod), (IMP)methodImplementation, "v@:");objc_allocateClassPair: নতুন ক্লাস তৈরি করার জন্য।Class newClass = objc_allocateClassPair([NSObject class], "NewClass", 0);method_getName: মেথডের নাম বের করার জন্য।SEL methodName = method_getName(methods[i]);class_copyMethodList: ক্লাসের মেথডের তালিকা কপি করতে।Method *methods = class_copyMethodList([NSObject class], &methodCount);
Objective-C Runtime এর সুবিধা
- ডাইনামিক আচরণ: আপনি রানটাইমে কোড পরিবর্তন বা মডিফাই করতে পারেন, যেমন নতুন মেথড বা ক্লাস যোগ করা, যা কোডের নমনীয়তা বৃদ্ধি করে।
- ডাইনামিক টাইপিং: রানটাইমে টাইপ চেকিং এবং মেথড রেজলিউশন করা হয়, যা কোড লেখার সময় ডেটার ধরন সম্পর্কে জানার প্রয়োজন কমিয়ে দেয়।
- রিফ্লেকশন: ক্লাসের সম্পর্কে তথ্য পাওয়া, এবং তার প্রপার্টি ও মেথড গুলি সম্পর্কে ডাইনামিক বিশ্লেষণ করা।
- কাস্টমাইজেশন: অবজেক্ট, ক্লাস, এবং মেথডের আচরণ কাস্টমাইজ করতে পারে, যা প্লাগইন বা এক্সটেনশনের মতো ব্যবহৃত হয়।
সারাংশ
Objective-C Runtime হল সেই সিস্টেম যা Objective-C কোডের আচরণ রানটাইমে পরিচালনা করে। এটি ডাইনামিক মেসেজ পাসিং, ক্লাস এবং মেথড ম্যানিপুলেশন, ডাইনামিক টাইপিং এবং রিফ্লেকশন সমর্থন করে, যা কোডের নমনীয়তা এবং শক্তি বৃদ্ধি করে। Runtime এর মাধ্যমে আপনি কোডকে আরও ডাইনামিকভাবে নিয়ন্ত্রণ করতে পারবেন, যা বেশিরভাগ অ্যাডভান্সড অ্যাপ্লিকেশন ডিজাইন এবং কাস্টমাইজেশন সহজ করে তোলে।
Objective-C তে, runtime একটি শক্তিশালী কনসেপ্ট যা আপনার কোড চলাকালীন সময়ে ক্লাস এবং মেথডগুলিকে ডাইনামিকভাবে পরিবর্তন, এক্সিকিউট বা ম্যানিপুলেট করার অনুমতি দেয়। Objective-C Runtime ইন্টারফেস আপনাকে কোডের মধ্যে runtime পর্যায়ে ক্লাসের তথ্য, মেথড, প্রপার্টি, ইত্যাদি এক্সেস এবং ম্যানিপুলেট করার ক্ষমতা প্রদান করে। এটি সাধারণত objc/runtime.h হেডার ফাইলে পাওয়া যায়।
এখানে Objective-C Runtime এর মাধ্যমে ক্লাস এবং মেথড ম্যানিপুলেশন কিভাবে করা যায় তা নিয়ে বিস্তারিত আলোচনা করা হলো।
1. Runtime দিয়ে ক্লাস ম্যানিপুলেশন
Objective-C তে, আপনি runtime এর মাধ্যমে একটি ক্লাসের ইনস্ট্যান্স বা অবজেক্টের টাইপ, মেথড এবং প্রপার্টি গুলি ডাইনামিকভাবে এক্সেস বা পরিবর্তন করতে পারেন। ক্লাসের ডাইনামিক ম্যানিপুলেশন করার জন্য objc_getClass এবং class_getInstanceVariable এর মতো ফাংশন ব্যবহৃত হয়।
ক্লাসের ধরন পরীক্ষা করা এবং ইনস্ট্যান্স তৈরি করা
objc_getClass এর মাধ্যমে আপনি runtime সময়ে একটি ক্লাসকে খুঁজে পেতে পারেন এবং তার পর alloc এর মাধ্যমে ইনস্ট্যান্স তৈরি করতে পারেন।
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Runtime এ ক্লাস লোড করা
Class carClass = objc_getClass("Car");
// ক্লাসের ইনস্ট্যান্স তৈরি করা
id myCar = [[carClass alloc] init];
NSLog(@"Car instance created: %@", myCar);
}
return 0;
}এখানে objc_getClass("Car") এর মাধ্যমে আমরা Car ক্লাসটি runtime এ এক্সেস করছি, এবং তার পর alloc করে তার একটি ইনস্ট্যান্স তৈরি করছি।
2. Runtime দিয়ে মেথড ম্যানিপুলেশন
Objective-C তে, runtime এর মাধ্যমে আপনি ক্লাসের মেথডগুলি এক্সেস, পরিবর্তন বা সরাসরি কল করতে পারেন। class_getInstanceMethod এবং method_setImplementation এর মাধ্যমে মেথডের কার্যকারিতা পরিবর্তন করা যায়। এই ধারণাটি খুবই শক্তিশালী, কারণ এর মাধ্যমে আপনি কোডের behaviour runtime পর্যায়ে পরিবর্তন করতে পারেন।
মেথড এক্সেস এবং পরিবর্তন
এখানে class_getInstanceMethod এবং method_setImplementation এর মাধ্যমে একটি মেথডের কার্যকারিতা পরিবর্তন করার উদাহরণ দেওয়া হলো।
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
// Original method
@interface Car : NSObject
- (void) drive;
@end
@implementation Car
- (void) drive {
NSLog(@"Car is driving...");
}
@end
// New method to replace the original
void customDrive(id self, SEL _cmd) {
NSLog(@"Custom drive method called...");
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *myCar = [[Car alloc] init];
// Get the original method (drive)
Method originalMethod = class_getInstanceMethod([Car class], @selector(drive));
// Replace the implementation with customDrive
method_setImplementation(originalMethod, (IMP)customDrive);
// Call the method after replacement
[myCar drive]; // This will now call customDrive instead of the original drive method.
}
return 0;
}এখানে:
class_getInstanceMethodব্যবহার করে আমরাCarক্লাসেরdriveমেথডটি এক্সেস করছি।method_setImplementationব্যবহার করে আমরা সেই মেথডের কার্যকারিতা (implementation)customDriveমেথড দিয়ে পরিবর্তন করছি।- পরে যখন
[myCar drive]কল করা হচ্ছে, এটি নতুনcustomDriveমেথডটি কল করবে।
3. Runtime দিয়ে প্রপার্টি ম্যানিপুলেশন
Runtime দিয়ে প্রপার্টি ম্যানিপুলেশন করা কিছুটা জটিল হতে পারে, তবে আপনি class_getProperty এবং object_getIvar ব্যবহার করে প্রপার্টির মান পরিবর্তন করতে পারেন।
প্রপার্টি এক্সেস এবং পরিবর্তন
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface Car : NSObject
@property NSString *model;
@end
@implementation Car
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Car *myCar = [[Car alloc] init];
// Set the 'model' property using runtime
Ivar modelIvar = class_getInstanceVariable([Car class], "_model");
object_setIvar(myCar, modelIvar, @"Tesla Model S");
// Get the 'model' property using runtime
NSString *carModel = object_getIvar(myCar, modelIvar);
NSLog(@"Car Model: %@", carModel); // Output: Tesla Model S
}
return 0;
}এখানে:
class_getInstanceVariableব্যবহার করে আমরা_modelইনস্ট্যান্স ভেরিয়েবলটি এক্সেস করেছি।object_setIvarব্যবহার করে আমরাmyCarঅবজেক্টেরmodelপ্রপার্টির মান সেট করেছি।- পরে
object_getIvarব্যবহার করে আমরা সেট করা মানটি পুনরায় এক্সেস করেছি।
4. Runtime ব্যবহার করার সুবিধা
- Dynamic Behavior: Runtime এর মাধ্যমে আপনি কোডের আচরণ পরিবর্তন করতে পারেন, যা অনেক কার্যকরী যখন আপনি কোনো কোডের মেথড বা প্রপার্টির কার্যকারিতা runtime এ পরিবর্তন করতে চান।
- Reflection: Objective-C তে runtime ব্যবহার করে আপনি ক্লাস, মেথড, এবং প্রপার্টি সম্পর্কে তথ্য জানতে পারেন, যা reflection এর মতো কাজ করে।
- Code Flexibility: Runtime এর মাধ্যমে আপনি কোডের আচরণ আরো নমনীয় এবং ফ্লেক্সিবল করতে পারেন, যেমন ডাইনামিক মেথড কল বা কাস্টম কোড তৈরি করা।
সারাংশ
- Runtime এর মাধ্যমে Objective-C তে class, method, এবং property গুলি dynamic ভাবে ম্যানিপুলেট করা সম্ভব।
- objc/runtime.h এর মাধ্যমে আপনি class_getClassMethod, method_setImplementation, class_getInstanceVariable, object_setIvar ইত্যাদি ফাংশন ব্যবহার করে কোডের behaviour পরিবর্তন করতে পারেন।
- এই টেকনিকগুলি খুবই শক্তিশালী, তবে সেগুলি সতর্কতার সাথে ব্যবহৃত হওয়া উচিত, কারণ এগুলি কোডের অন্য অংশগুলিতে unexpected results সৃষ্টি করতে পারে।
objc_msgSend এবং Method Swizzling দুটি গুরুত্বপূর্ণ কনসেপ্ট Objective-C তে, যা প্রোগ্রামের চলাচল পরিবর্তন বা ডাইনামিক্যালি মেথডকে প্রভাবিত করার জন্য ব্যবহৃত হয়। এগুলি অত্যন্ত শক্তিশালী টুলস যা ডেভেলপারদের লো-লেভেল কার্যক্রম পরিচালনা করতে এবং কোডের আচরণ পরিবর্তন করতে সহায়তা করে।
এখানে, আমরা objc_msgSend এবং Method Swizzling এর ব্যবহার, তাদের উদ্দেশ্য এবং কীভাবে এগুলি কাজ করে তা বিশ্লেষণ করব।
1. objc_msgSend
objc_msgSend হল একটি ফাংশন যা Objective-C তে মেসেজ পাসিং সিস্টেমকে বাস্তবায়িত করে। এটি মূলত ডাইনামিক ডিসপ্যাচ বা মেসেজ সেন্টিং এর জন্য ব্যবহৃত হয়।
Objective-C তে, যখন একটি মেথড কল করা হয়, তখন এটি আসলে objc_msgSend ফাংশনকে কল করার মাধ্যমে বাস্তবায়িত হয়। এটি অবজেক্টের ক্লাসের সাথে সম্পর্কিত মেথডের জন্য মেসেজ পাঠায় এবং মেথড এক্সিকিউট করে।
objc_msgSend এর সাধারণ কাজ:
- মেসেজ পাঠানো: অবজেক্টের মেথডের নাম এবং প্যারামিটারগুলোর মাধ্যমে একটি মেসেজ পাঠানো হয়।
- ডাইনামিক ডিসপ্যাচ: এটি অবজেক্টের ক্লাসের সাথে সম্পর্কিত মেথড খুঁজে বের করে এবং এক্সিকিউট করে।
objc_msgSend এর উদাহরণ:
#import <objc/message.h>
@interface Person : NSObject
- (void) sayHello;
@end
@implementation Person
- (void) sayHello {
NSLog(@"Hello from Person!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
// Method call using objc_msgSend
objc_msgSend(person, @selector(sayHello)); // sayHello মেথড কল
}
return 0;
}এখানে, objc_msgSend মেথডটি sayHello মেসেজটি person অবজেক্টে পাঠিয়েছে। এটি ডাইনামিক্যালি sayHello মেথড খুঁজে বের করে এবং এক্সিকিউট করে।
মুখ্য বৈশিষ্ট্য:
- ডাইনামিক ডিসপ্যাচ: যখন একটি মেথড কল করা হয়, তখন এটি আসলে
objc_msgSendএর মাধ্যমে মেসেজ পাঠিয়ে মেথডটি এক্সিকিউট হয়। - ডাইনামিক্যালি মেসেজ পাঠানো: মেথডের নাম এবং প্যারামিটারগুলোকে ডাইনামিক্যালি আর্গুমেন্ট হিসেবে পাস করা হয়।
2. Method Swizzling
Method Swizzling একটি ডাইনামিক কৌশল যা Objective-C তে ব্যবহার করে, যার মাধ্যমে আপনি runtime এ একটি মেথডের কার্যক্রম পরিবর্তন করতে পারেন। এটি মূলত ক্লাসের মেথডের আচরণ পরিবর্তন করার জন্য ব্যবহৃত হয়, অর্থাৎ, আপনি একটি মেথডকে অন্য একটি মেথডের সাথে সুইজ (swap) করে দিতে পারেন। এর মাধ্যমে, আপনার কোডের behavior runtime এ পরিবর্তন করা সম্ভব হয়।
Method Swizzling অনেক সময় যখন আপনি কোন নির্দিষ্ট মেথডের আচরণ পরিবর্তন করতে চান, কিন্তু আপনি ঐ মেথডের সোর্স কোড পরিবর্তন করতে পারবেন না, তখন এটি ব্যবহৃত হয়।
Method Swizzling কিভাবে কাজ করে?
- আপনি প্রথমে দুটি মেথড নির্বাচন করেন।
- এরপর,
method_exchangeImplementationsফাংশন ব্যবহার করে ঐ দুটি মেথডের কার্যক্রম বদলে দেন। - এর ফলে, একটি মেথডের জন্য আসলে অন্য মেথডটি কল হয়।
Method Swizzling এর উদাহরণ:
#import <objc/runtime.h>
@interface Person : NSObject
- (void) sayHello;
@end
@implementation Person
- (void) sayHello {
NSLog(@"Hello from Person!");
}
@end
// Swizzling function to swap methods
void SwizzleMethods(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// Swap the methods
method_exchangeImplementations(originalMethod, swizzledMethod);
}
@implementation Person (Swizzling)
- (void) sayHelloSwizzled {
NSLog(@"Swizzled Hello from Person!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
// Swizzling methods
SwizzleMethods([Person class], @selector(sayHello), @selector(sayHelloSwizzled));
// Now call the sayHello method
[person sayHello]; // Output: Swizzled Hello from Person!
}
return 0;
}ব্যাখ্যা:
sayHelloমেথডটি সঠিকভাবে কাজ করে, কিন্তু আমরা এটিsayHelloSwizzledমেথডের সাথে সুইজ করে দিয়েছি।method_exchangeImplementationsফাংশনটি ব্যবহার করে মেথডের কার্যক্রম পরিবর্তন করা হয়েছে। এর ফলে, যখন আমরাsayHelloকল করি, তখন আসলেsayHelloSwizzledকল হয়।
Method Swizzling এর ব্যবহারিক ক্ষেত্রে:
- Debugging বা Logging: আপনি যখন কোনো মেথডের আগে বা পরে অতিরিক্ত লগিং বা debugging করতে চান, তখন Method Swizzling ব্যবহার করে একটি মেথডের আচরণ পরিবর্তন করতে পারেন।
- Third-party Libraries: কিছু থার্ড-পার্টি লাইব্রেরি যেমন CocoaPods বা Swizzle নিজেদের মেথডের আচরণ পরিবর্তন করার জন্য Swizzling ব্যবহার করে।
- Category ব্যবহার করে মেথড সুইজিং: Categories ব্যবহার করে আপনি একটি ক্লাসের মেথড আচরণ পরিবর্তন করতে পারেন, যেমন, কোন থার্ড-পার্টি ক্লাসের মেথডের কার্যক্রম বদলানো।
সারাংশ
objc_msgSend: এটি Objective-C তে মেসেজ পাসিং সিস্টেমের মূল ফাংশন, যা ডাইনামিক ডিসপ্যাচ করতে ব্যবহৃত হয়। এটি মেথড কলের মাধ্যমে অবজেক্টের সাথে মেসেজ পাঠায় এবং সেই মেসেজের সাথে সম্পর্কিত মেথড এক্সিকিউট করে।- Method Swizzling: এটি একটি ডাইনামিক কৌশল যেখানে runtime এ মেথডের কার্যক্রম পরিবর্তন করা হয়। এটি মূলত ক্লাসের মেথডের আচরণ পরিবর্তন করার জন্য ব্যবহৃত হয় এবং কখনও কখনও থার্ড-পার্টি কোড বা ডিবাগিংয়ের জন্য ব্যবহৃত হতে পারে।
Method Swizzling এবং objc_msgSend এর মাধ্যমে ডেভেলপাররা অ্যাপ্লিকেশনের আচরণ পরিবর্তন করতে এবং runtime এ মেথড কলের জন্য আরও কার্যকরী ও গতিশীল কৌশল তৈরি করতে সক্ষম হন।
Runtime programming এবং Dynamic Method Resolution হল Objective-C তে ডেভেলপমেন্টের শক্তিশালী কনসেপ্ট, যা প্রোগ্রাম চলাকালীন সময়ে কোডের আচরণ পরিবর্তন করতে এবং নতুন কার্যকলাপ যুক্ত করতে সহায়তা করে। Objective-C তে Runtime ব্যাপকভাবে ব্যবহার করা হয়, বিশেষ করে যখন আপনি ডাইনামিকভাবে মেথড রেজোলিউশন, ডাইনামিক ক্লাস বা অবজেক্ট তৈরি করতে চান। এটি reflection এবং dynamic dispatch এর মতো ধারণাগুলোর জন্য প্রয়োজনীয়।
1. Runtime Programming in Objective-C
Runtime Programming হল সেই প্রোগ্রামিং কৌশল যেখানে প্রোগ্রাম চলাকালীন সময়ে কিছু আচরণ পরিবর্তন করা হয় বা নতুন ক্লাস, অবজেক্ট, মেথড বা প্রপার্টি তৈরি করা হয়। Objective-C তে runtime প্রোগ্রামিং শক্তিশালী এবং ডাইনামিক। এটি প্রোগ্রামারের জন্য অনেক ফ্লেক্সিবিলিটি এবং কাস্টমাইজেশন প্রদান করে।
Objective-C Runtime:
Objective-C তে runtime সম্পর্কিত অনেক ধরনের ফাংশন এবং API রয়েছে যেগুলোর মাধ্যমে আপনি:
- ক্লাসের তথ্য পেতে পারেন।
- মেথড এবং প্রপার্টির ইনফরমেশন খুঁজে পেতে পারেন।
- ডাইনামিক ক্লাস তৈরি করতে পারেন।
Common Runtime Functions:
class_getName: ক্লাসের নাম পেতে।class_addMethod: একটি ক্লাসে নতুন মেথড যোগ করতে।object_setClass: একটি অবজেক্টের ক্লাস পরিবর্তন করতে।
উদাহরণ:
#import <objc/runtime.h>
@interface MyClass : NSObject
- (void) sayHello;
@end
@implementation MyClass
- (void) sayHello {
NSLog(@"Hello, World!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyClass *obj = [[MyClass alloc] init];
[obj sayHello]; // আউটপুট: Hello, World!
// Runtime API ব্যবহার করে মেথড পরিবর্তন
Method originalMethod = class_getInstanceMethod([MyClass class], @selector(sayHello));
class_addMethod([MyClass class], @selector(sayGoodbye), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
[obj performSelector:@selector(sayGoodbye)]; // আউটপুট: Hello, World!
}
return 0;
}এখানে, class_addMethod ব্যবহার করে আমরা runtime-এ sayGoodbye মেথডটি যুক্ত করেছি, যা আসলে sayHello মেথডের কার্যকারিতা ধারণ করছে।
2. Dynamic Method Resolution (ডাইনামিক মেথড রেজোলিউশন)
Dynamic Method Resolution হল সেই প্রক্রিয়া যেখানে Objective-C runtime-এ মেথড কল করার আগে তা প্রোগ্রামmatically রেজোলভ করা হয়। এটি একটি ডাইনামিক প্রক্রিয়া, যার মাধ্যমে আপনি একটি মেথড চলাকালীন সময়ে রেজোলভ (সমাধান) করতে পারেন। অর্থাৎ, যদি কোনো মেথড অবজেক্টে না থাকে, তাহলে runtime-এ তা তৈরি বা রেজোলভ করা যায়।
Dynamic Method Resolution Process:
- যখন কোনো মেথড একটি অবজেক্টে কল করা হয়, কিন্তু সেই মেথড অবজেক্টে বিদ্যমান না থাকে, তখন Objective-C
resolveInstanceMethod:বাresolveClassMethod:মেথড কল করে। - এই মেথডগুলোর মাধ্যমে, আপনি একটি কাস্টম মেথড রেজোলভ করতে পারেন, এবং যখন
resolveInstanceMethod:বাresolveClassMethod:কল করা হয়, তখন মেথড সঞ্চালিত হবে।
resolveInstanceMethod: এবং resolveClassMethod:
resolveInstanceMethod:: একটি ইনস্ট্যান্স মেথড রেজোলভ করতে ব্যবহৃত হয়।resolveClassMethod:: একটি ক্লাস মেথড রেজোলভ করতে ব্যবহৃত হয়।
উদাহরণ: Dynamic Method Resolution
#import <objc/runtime.h>
@interface MyClass : NSObject
@end
@implementation MyClass
// মেথড রেজোলভ করার জন্য
+ (BOOL) resolveInstanceMethod:(SEL)sel {
if (sel == @selector(sayGoodbye)) {
class_addMethod([self class], sel, (IMP)goodbye, "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
void goodbye(id self, SEL _cmd) {
NSLog(@"Goodbye, World!");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyClass *obj = [[MyClass alloc] init];
[obj performSelector:@selector(sayGoodbye)]; // আউটপুট: Goodbye, World!
}
return 0;
}এখানে, resolveInstanceMethod: ব্যবহার করে আমরা sayGoodbye মেথড runtime-এ goodbye ফাংশন দিয়ে রেজোলভ করেছি।
class_addMethodব্যবহার করে নতুন মেথড যুক্ত করা হয়, যা ডাইনামিকভাবে কল করা যায়।IMPহল মেথড ইমপ্লিমেন্টেশনের পয়েন্টার, যাgoodbyeফাংশনে রেফারেন্স করে।
3. Benefits of Runtime Programming and Dynamic Method Resolution
- Flexibility: রানটাইমে ক্লাস এবং মেথড তৈরি করার ক্ষমতা কোডকে অত্যন্ত ফ্লেক্সিবল এবং কাস্টমাইজেবল করে তোলে। এটি বিশেষ করে প্লাগইন সিস্টেম বা ডাইনামিক লোডিংয়ের জন্য উপকারী।
- Late Binding: ডাইনামিক মেথড রেজোলভেশন ডাইনামিক লেট-বাইন্ডিং সক্ষম করে, যার মাধ্যমে কোড কম্পাইল হওয়ার পরেও মেথডের আচরণ পরিবর্তন করা যায়।
- Decoupling: এতে কম্পোনেন্টগুলির মধ্যে শক্তিশালী আণবিক সংযোগ সৃষ্টি করা হয়, যার ফলে কোডের পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়।
4. Use Cases of Dynamic Method Resolution
- Delegation: ডেলিগেট প্যাটার্নের সময় dynamic method resolution ব্যবহৃত হয়। যখন ডেলিগেট মেথড কল করা হয়, কিন্তু ডেলিগেট অবজেক্টে সেই মেথড না থাকে, তখন এটি ডাইনামিকভাবে রেজোলভ করা যায়।
- Error Handling: যখন কোনো মেথড অবজেক্টে পাওয়া যায় না, তখন resolveInstanceMethod বা resolveClassMethod ব্যবহার করে তা রেজোলভ করা সম্ভব।
- Method Swizzling: Objective-C তে, মেথড সুইজলিংয়ের জন্য এই কৌশল ব্যবহার করা হয়, যেখানে দুইটি মেথডের বাস্তবায়ন একে অপরের সাথে বদলে দেয়া হয়।
5. Conclusion
- Runtime Programming হল প্রোগ্রাম চলাকালীন সময়ে কোডের আচরণ পরিবর্তন বা সম্প্রসারণ করার ক্ষমতা, যা Objective-C তে অত্যন্ত কার্যকর।
- Dynamic Method Resolution ব্যবহার করে আপনি runtime-এ মেথড কল করার সময় ত্রুটি সমাধান করতে পারেন এবং ডাইনামিকভাবে মেথড রেজোলভ করতে পারেন।
- Objective-C runtime প্রোগ্রামিং একটি শক্তিশালী এবং নমনীয় ব্যবস্থা, যা সফটওয়্যার ডেভেলপমেন্টে বিভিন্ন পরিস্থিতিতে ব্যবহার করা যায়, যেমন প্লাগইন সিস্টেম, ডেলিগেট প্যাটার্ন এবং error handling এর ক্ষেত্রে।
Read more