有四種方法可以使一個回調:
函數指針,如果你真的想你可以做一個函數指針,但它不推薦。它的做法與你在C中做的相同。問題是你不能使用指向Objective-C方法的函數指針。它看起來是這樣的:
void callback(/* Some args */) {
// Some callback.
}
- (void)doSomethingAndCallThisFunctionWhenDone:(void(*)(/* Some args */))func {
// Do something.
if (func)
func(/* Some args */);
}
- (void)start {
[self doSomethingAndCallThisFunctionWhenDone:&callback];
}
選擇器您可以使用-performSelector :.它看起來像這樣:
- (void)doSomethingAndCallTarget:(id)target withSelector:(SEL)sel {
// Do something.
[target performSelector:sel];
}
- (void)start {
SomeOtherObject * someOtherObject = [[SomeOtherObject alloc] init];
[self doSomethingAndCallTarget:someOtherObject withSelector:@selector(MyCallback)];
}
代表使用委託。這與UITableViewDelegate/UITableViewDataSource類似。請參閱Apple docs here。你可能不喜歡這樣:
- (void)doSomethingDelegate:(id<MyCallbackObject>)delegate {
[delegate retain];
// Do something.
[delegate performMyCallback]; // -performMyCallback must be declared in the MyCallbackObject protocol and implemented by SomeOtherObject.
[delegate release];
}
- (void)start {
id<MyCallbackObject> someOtherObject = [[SomeOtherObject alloc] init];
[self doSomethingDelegate:someOtherObject];
[someOtherObject release];
}
塊的首選方法回調是使用塊。它們僅適用於iOS 4.0或Mac OS X 10.6+。它看起來是這樣的:
- (void)doSomethingAndCallThisBlockWhenDone:(void(^)(/* Some args */))block {
[block copy];
// Do something.
if (block)
block(/* Some args */);
[block release];
}
- (void)start {
[self doSomethingAndCallThisBlockWhenDone:^void(/* Some args */){ // Return type and arguments may be omitted if you don't have any.
// Your callback
}];
}
正如你可以使用塊看,它更容易閱讀和您的回調是內聯與您的代碼。這特別好,所以你不必追捕它。塊有更多的好處,但我不可能在這裏覆蓋它們。
最後一件事,如果你使用塊,你將要使用typedef
,所以你不必鍵入晦澀塊類型,如void(^)(/* Some args */)
所有的時間。該typedef
看起來是這樣的:
typdef void(^MyCallback)(/* Some args */);
然後,你可以宣佈你這樣的方法:
- (void)doSomethingAndCallThisBlockWhenDone:(MyCallback)block;
更新:
我已經展示瞭如何實現不同的更詳細技術(見上文)。
但是這是什麼SomeOtherObject的一面呢?需要在SomeOtherObject中聲明什麼以及它需要做什麼? 它必須有一個doSomethingAndCallThisFunctionWhenUrDone。但是它實際上需要做什麼來調用對象ThisObject的所述方法? 目前爲止, – Joe
我擴展了我的答案以顯示更多實施細節。對於函數指針和塊,你不需要一個對象來調用它們,但是你可以作爲參數傳遞對象。 – rbrown