[英]How to perform Callbacks in Objective-C
如何在Objective-C中執行回調函數?
我只想看一些完整的例子,我應該理解它。
為了完整性,由於StackOverflow RSS只是為我隨機復活了這個問題,另一個(更新的)選項是使用塊:
@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);
}];
通常,目標C中的回調是通過代理完成的。 這是自定義委托實現的示例;
頭文件:
@interface MyClass : NSObject {
id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end
@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end
實施(.m)文件
@implementation MyClass
- (void)setDelegate:(id)aDelegate {
delegate = aDelegate; /// Not retained
}
- (void)doSomething {
[delegate myClassWillDoSomething:self];
/* DO SOMETHING */
[delegate myClassDidDoSomething:self];
}
@end
這說明了一般方法。 您在NSObject上創建了一個聲明回調方法名稱的類別。 NSObject實際上並沒有實現這些方法。 這種類型被稱為非正式協議,您只是說許多對象可能實現這些方法。 它們是一種轉發聲明選擇器類型簽名的方法。
接下來,您有一些對象是“MyClass”的委托,MyClass根據需要調用委托上的委托方法。 如果你的委托回調是可選的,你通常會在調度站點用“if([delegate respondsToSelector:@selector(myClassWillDoSomething :)){”來保護它們。 在我的示例中,委托需要實現這兩種方法。
您也可以使用@protocol定義的正式協議,而不是非正式協議。 如果這樣做,您將更改委托setter的類型,並將實例變量更改為“ id <MyClassDelegate>
”而不是“ id
”。
此外,您會注意到代理人未被保留。 這通常是因為“擁有”“MyClass”實例的對象通常也是委托。 如果MyClass保留了其委托,則會有一個保留周期。 在類的dealloc方法中有一個好主意,它有一個MyClass實例,並且它是委托來清除該委托引用,因為它是一個弱后向指針。 否則,如果某些東西使MyClass實例保持活動狀態,那么你將有一個懸空指針。
這是一個保持委托概念的示例,只是進行原始回調。
@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
通常,方法 - [Foo doSomethingAndNotifyObject:withSelector:]將是異步的,這將使回調比它在這里更有用。
為了使這個問題保持最新,iOS 5.0引入ARC意味着可以更簡潔地使用Blocks實現這一點:
@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);
}];
如果你忘記了Objective-C的Block語法,總會有F **** ng Block語法。
CallBack:Objective C中有4種類型的回調
選擇器類型 :您可以看到NSTimer,UIPangesture是Selector回調的示例。 用於非常有限的代碼執行。
委托類型 :Apple框架中的常用和最常用。 UITableViewDelegate,NSNURLConnectionDelegate。 它們通常用於顯示從服務器異步下載許多圖像等。
如果有任何其他答案,請告訴我。 我會很感激的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.