উদ্দেশ্য-সি-তে কীভাবে কলব্যাকগুলি সম্পাদন করবেন perform


119

উদ্দেশ্য-সি-তে কল ব্যাক ফাংশন কীভাবে সম্পাদন করবেন?

আমি কেবল কয়েকটি সমাপ্ত উদাহরণ দেখতে চাই এবং আমার এটি বুঝতে হবে।

উত্তর:


94

সাধারণত, উদ্দেশ্য সিতে কলব্যাকগুলি প্রতিনিধিদের সাথে সম্পন্ন হয়। এখানে কাস্টম প্রতিনিধি বাস্তবায়নের উদাহরণ রয়েছে;


শিরোনাম ফাইল:

@interface MyClass : NSObject {
    id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end

@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end

বাস্তবায়ন (। মি) ফাইল

@implementation MyClass
- (void)setDelegate:(id)aDelegate {
    delegate = aDelegate; /// Not retained
}

- (void)doSomething {
    [delegate myClassWillDoSomething:self];
    /* DO SOMETHING */
    [delegate myClassDidDoSomething:self];
}
@end

এটি সাধারণ পদ্ধতির চিত্রিত করে। আপনি এনএসবজেক্টে একটি বিভাগ তৈরি করেছেন যা আপনার কলব্যাক পদ্ধতির নামগুলি ঘোষণা করে। এনএসবজেক্ট আসলে এই পদ্ধতিগুলি বাস্তবায়ন করে না। এই ধরণের বিভাগকে একটি অনানুষ্ঠানিক প্রোটোকল বলা হয়, আপনি কেবল বলছেন যে অনেকগুলি এই পদ্ধতিগুলি প্রয়োগ করতে পারে। তারা নির্বাচকের নির্বাচনের স্বাক্ষরের প্রকারটি প্রেরণের এক উপায়।

এর পরে আপনার কিছু বিষয় "মাইক্লাস" এর প্রতিনিধি হতে হবে এবং মাইক্লাস ডেলিগেটের ডেলিগেট পদ্ধতিগুলিকে যথাযথ হিসাবে ডাকে। যদি আপনার প্রতিনিধি কলব্যাকগুলি areচ্ছিক হয় তবে আপনি সাধারণত "যদি ([প্রতিনিধি প্রতিক্রিয়াশক্তি নির্বাচন করুন: @ নির্বাচক (মাই ক্লাসওয়িলডোসোমথিং :)) {" এর মতো কিছু দিয়ে প্রেরণ সাইটে তাদের রক্ষা করবেন। "।" আমার উদাহরণে, প্রতিনিধি উভয় পদ্ধতি বাস্তবায়নের প্রয়োজন।

অনানুষ্ঠানিক প্রোটোকলের পরিবর্তে, আপনি @ প্রোটোকলের সাথে সংজ্ঞায়িত একটি ফর্মাল প্রোটোকলও ব্যবহার করতে পারেন। যদি আপনি এটি করেন, আপনি ডেলিগেট সেটারের ধরণটি পরিবর্তন করতে পারেন, এবং উদাহরণ পরিবর্তনশীল " id <MyClassDelegate>" পরিবর্তে " " পরিবর্তিত হবে id

এছাড়াও, আপনি লক্ষ্য করবেন যে প্রতিনিধিটি ধরে রাখা হয়নি। এটি সাধারণত করা হয় কারণ "মাইক্লাস" এর "উদাহরণস্বরূপ" অবজেক্টটি সাধারণত প্রতিনিধিও হয়। মাইক্লাস যদি এটির প্রতিনিধি ধরে রাখে, তবে সেখানে ধরে রাখার চক্র থাকবে। এটি একটি ক্লাসের ডিলোক পদ্ধতিতে একটি ভাল ধারণা যেটির একটি মাইক্লাস উদাহরণ রয়েছে এবং এটি তার প্রতিনিধি যে সেই প্রতিনিধি রেফারেন্সটি পরিষ্কার করার জন্য এটি দুর্বল ব্যাক পয়েন্টার। অন্যথায় যদি কিছু মাইক্লাস উদাহরণটি বাঁচিয়ে রাখে তবে আপনার কাছে ঝুঁকির পয়েন্টার থাকবে।


+1 ভাল পুঙ্খানুপুঙ্খ উত্তর। কেকের উপর আইসিং প্রতিনিধিদের সম্পর্কে আরও গভীরতার সাথে অ্যাপল ডকুমেন্টেশনের লিঙ্ক হবে। :-)
কুইন টেলর

জোন, আপনার সাহায্যের জন্য অনেক ধন্যবাদ। আমি সত্যিই আপনার সাহায্য তারিফ করা. আমি এই সম্পর্কে দুঃখিত, কিন্তু আমি উত্তরের বিষয়ে খুব পরিষ্কার নয় am বার্তা .m একটি ক্লাস যা ডোসোমিংথিং ফাংশন কলের সময় নিজেকে প্রতিনিধি হিসাবে সেট করে। ব্যবহারকারীরা যে ডাকে কলব্যাক ফাংশন কল করছে তা কি কিছু করছে? যেহেতু আমি এই ছাপের মধ্যে আছি যে ব্যবহারকারী ডসোমিংথিং কল করে এবং আপনার কল ব্যাক ফাংশনগুলি হ'ল মাই ক্লাসওয়িলডোসোমথিংগ এবং মাই ক্লাসডিডডোসোমিংথিং। পাশাপাশি, আপনি কীভাবে একটি উচ্চতর শ্রেণি তৈরি করবেন যা কল ব্যাক ফাংশনে কল করে তা আমাকে দেখাতে পারেন। আমি একজন সি প্রোগ্রামার তাই আমি এখনও ওবজ-সি পরিবেশের সাথে খুব বেশি পরিচিত নই।
রিচ সংযোগ

"বার্তা .এম" এর অর্থ হ'ল আপনি। মি ফাইল। আপনার একটি পৃথক শ্রেণি আছে, আসুন একে "ফু" বলুন। ফু-তে একটি "মাইক্লাস * মাই ক্লাস" পরিবর্তনশীল থাকবে এবং কোনও কোনও মুহুর্তে ফু বলত "[মাই ক্লাস সেটডেলিগেট: স্ব]"। এর পরে যে কোনও মুহুর্তে, foo সহ কেউ যদি মাইক্লাসের সেই উদাহরণটিতে doSomethingMethod আহ্বান করে, foo এর myClassWillDoSomething এবং মাই ক্লাসডিডডোসোমথিং পদ্ধতি চালু করা হত। আমি প্রকৃতপক্ষে কেবল একটি দ্বিতীয় আলাদা উদাহরণ পোস্ট করব যা প্রতিনিধিদের ব্যবহার করে না।
জন হেস

আমি মনে করি না। মি মানে "বার্তা"।
চক


140

সম্পূর্ণতার জন্য, স্ট্যাকওভারফ্লো আরএসএস যেহেতু আমার জন্য এলোমেলোভাবে প্রশ্নটি পুনরুত্থিত করেছে, অন্য (নতুন) বিকল্পটি ব্লকগুলি ব্যবহার করে:

@interface MyClass: NSObject
{
    void (^_completionHandler)(int someParameter);
}

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler;
@end


@implementation MyClass

- (void) doSomethingWithCompletionHandler:(void(^)(int))handler
{
    // NOTE: copying is very important if you'll call the callback asynchronously,
    // even with garbage collection!
    _completionHandler = [handler copy];

    // Do stuff, possibly asynchronously...
    int result = 5 + 3;

    // Call completion handler.
    _completionHandler(result);

    // Clean up.
    [_completionHandler release];
    _completionHandler = nil;
}

@end

...

MyClass *foo = [[MyClass alloc] init];
int x = 2;
[foo doSomethingWithCompletionHandler:^(int result){
    // Prints 10
    NSLog(@"%i", x + result);
}];

2
@ অহরুমান: "অকার্যকর (com _ কমপ্লেশনহ্যান্ডলার)" (কিছুটা প্যারামিটার) - এ "^" - চরিত্রটি কী করে; " এর অর্থ কি? আপনি কি ব্যাখ্যা করতে পারেন যে রেখাটি কি করে?
কনরাড হাফনার

2
আপনি কেন কলব্যাক হ্যান্ডলার অনুলিপি করতে হবে তার একটি ব্যাখ্যা সরবরাহ করতে পারেন?
এলিয়ট চান্স

52

এখানে একটি উদাহরণ যা প্রতিনিধিদের ধারণাগুলি বাইরে রাখে এবং কেবল একটি কাঁচা কল ফিরে আসে does

@interface Foo : NSObject {
}
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector;
@end

@interface Bar : NSObject {
}
@end

@implementation Foo
- (void)doSomethingAndNotifyObject:(id)object withSelector:(SEL)selector {
    /* do lots of stuff */
    [object performSelector:selector withObject:self];
}
@end

@implementation Bar
- (void)aMethod {
    Foo *foo = [[[Foo alloc] init] autorelease];
    [foo doSomethingAndNotifyObject:self withSelector:@selector(fooIsDone:)];
}

- (void)fooIsDone:(id)sender {
    NSLog(@"Foo Is Done!");
}
@end

সাধারণত পদ্ধতিটি - [ফু ডুসোমিংথিং অ্যান্ড নটিফাইবজেক্ট: উইথ সিলেক্টর:] এমন অ্যাসিনক্রোনাস হবে যা কলব্যাকটিকে এখানে উপস্থিতির চেয়ে আরও দরকারী করে তুলবে।


1
অনেক ধন্যবাদ জন। আমি আপনার মন্তব্যের পরে আপনার প্রথম কলব্যাক বাস্তবায়ন বুঝতে পারি। পাশাপাশি, আপনার ২ য় কলব্যাক বাস্তবায়ন আরও সহজ। দুটোই খুব ভাল।
রিচ কানেকশন

1
এই জোন পোস্ট করার জন্য ধন্যবাদ, এটি খুব সহায়ক ছিল। আমাকে [অবজেক্ট পারফরমেশনসিলিটরওইটজেক্ট: স্ব] পরিবর্তন করতে হয়েছিল; to [অবজেক্ট পারফেক্টসলেক্টর: সিলেক্টর উইথ অবজেক্ট: সেল্ফ]; যাতে এটি সঠিকভাবে কাজ করতে পারে।
বাঞ্জার

16

এই প্রশ্নটিকে আপ টু ডেট রাখার জন্য, আইওএস 5.0 এর এআরসি প্রবর্তনের অর্থ ব্লকগুলি আরও সংক্ষিপ্তভাবে ব্যবহার করে এটি অর্জন করা যেতে পারে :

@interface Robot: NSObject
+ (void)sayHi:(void(^)(NSString *))callback;
@end

@implementation Robot
+ (void)sayHi:(void(^)(NSString *))callback {
    // Return a message to the callback
    callback(@"Hello to you too!");
}
@end

[Robot sayHi:^(NSString *reply){
  NSLog(@"%@", reply);
}];

আপনি যদি কখনও ওজেক্টিভ-সি এর ব্লক সিনট্যাক্সটি ভুলে যান তবে সর্বদা এফ **** এনজি ব্লক সিনট্যাক্স থাকে।


@ ইনটারফেসে থাকা উচিত + (void)sayHi:(void(^)(NSString *reply))callback;নয়+ (void)sayHi:(void(^)(NSString *))callback;
টিম 007

পূর্বোক্ত F **** এনজি ব্লক সিনট্যাক্স অনুসারে নয় : - (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;(নোট parameterTypesনয় parameters)
রায়ান ব্রোডি

4

কলব্যাক: অবজেক্টিভ সি তে 4 ধরণের কলব্যাক রয়েছে

  1. নির্বাচক প্রকার : আপনি এনটিএসটাইমার দেখতে পাচ্ছেন, ইউআইপিএনজাস্টচারটি নির্বাচক কলব্যাকের উদাহরণ। কোড খুব সীমিত কার্যকর জন্য ব্যবহৃত।

  2. প্রতিনিধি প্রকার : অ্যাপল ফ্রেমওয়ার্কে সাধারণ এবং সর্বাধিক ব্যবহৃত। ইউআইটিএবলভিউ ডেলিগেট, এনএসএনআরএল সংযোগডেলিগেট। এগুলি সাধারণত সার্ভার থেকে অ্যাসিঙ্ক্রোনাসে অনেকগুলি চিত্র ডাউনলোড করা দেখাতে ব্যবহৃত হয় etc.

  3. এনএসনোটিকেশন : নোটিফিকেশন সেন্টার অবজেক্টিভ সি এর অন্যতম বৈশিষ্ট্য যা ঘটনাটি ঘটে যখন অনেকগুলি প্রাপ্তিদেরকে অবহিত করতে ব্যবহৃত হত।
  4. ব্লকস : অবজেক্টিভ সি প্রোগ্রামিংয়ে ব্লক বেশি ব্যবহৃত হয়। এটি দুর্দান্ত বৈশিষ্ট্য এবং কোডের খণ্ডটি কার্যকর করার জন্য ব্যবহৃত হয়। আপনি বুঝতে টিউটোরিয়াল উল্লেখ করতে পারেন: ব্লকস টিউটোরিয়াল

এর জন্য অন্য কোনও উত্তর দিলে দয়া করে আমাকে জানান। আমি কৃতজ্ঞ হব.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.