Bagaimana cara melakukan fungsi panggilan balik di Objective-C?
Saya hanya ingin melihat beberapa contoh lengkap dan saya harus memahaminya.
Bagaimana cara melakukan fungsi panggilan balik di Objective-C?
Saya hanya ingin melihat beberapa contoh lengkap dan saya harus memahaminya.
Jawaban:
Biasanya, callback di objektif C dilakukan dengan delegasi. Berikut adalah contoh implementasi delegasi kustom;
File Header:
@interface MyClass : NSObject {
id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end
@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end
File Implementasi (.m)
@implementation MyClass
- (void)setDelegate:(id)aDelegate {
delegate = aDelegate; /// Not retained
}
- (void)doSomething {
[delegate myClassWillDoSomething:self];
/* DO SOMETHING */
[delegate myClassDidDoSomething:self];
}
@end
Itu menggambarkan pendekatan umum. Anda membuat kategori di NSObject yang mendeklarasikan nama metode callback Anda. NSObject tidak benar-benar menerapkan metode ini. Jenis kategori ini disebut protokol informal, Anda hanya mengatakan bahwa banyak objek mungkin mengimplementasikan metode ini. Mereka adalah cara untuk meneruskan menyatakan jenis tanda tangan pemilih.
Selanjutnya Anda memiliki beberapa objek menjadi delegasi dari "MyClass" dan MyClass memanggil metode delegasi pada delegasi yang sesuai. Jika callback delegasi Anda bersifat opsional, Anda biasanya akan menjaganya di situs pengiriman dengan sesuatu seperti "if ([delegate respondsToSelector: @selector (myClassWillDoSomething :)) {". Dalam contoh saya, delegasi diharuskan untuk mengimplementasikan kedua metode tersebut.
Selain protokol informal, Anda juga dapat menggunakan protokol formal yang ditentukan dengan @protocol. Jika Anda melakukan itu, Anda akan mengubah jenis penyetel delegasi, dan variabel contoh menjadi " id <MyClassDelegate>
" bukan hanya " id
".
Selain itu, Anda akan melihat delegasi tidak dipertahankan. Hal ini biasanya dilakukan karena objek yang "memiliki" instance "MyClass" biasanya juga merupakan delegasi. Jika MyClass mempertahankan delegasinya, maka akan ada siklus retensi. Ada baiknya dalam metode dealloc kelas yang memiliki instance MyClass dan delegasinya adalah untuk menghapus referensi delegasi karena ini adalah penunjuk punggung yang lemah. Jika tidak, jika sesuatu membuat instance MyClass tetap hidup, Anda akan memiliki penunjuk yang menggantung.
Untuk kelengkapan, karena StackOverflow RSS secara acak membangkitkan pertanyaan untuk saya, opsi lain (lebih baru) adalah menggunakan blok:
@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);
}];
Berikut adalah contoh yang membuat konsep delegasi tetap keluar, dan hanya melakukan panggilan mentah.
@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
Biasanya metode - [Foo doSomethingAndNotifyObject: withSelector:] akan menjadi asinkron yang akan membuat callback lebih berguna daripada di sini.
Untuk menjaga agar pertanyaan ini tetap mutakhir, pengenalan ARC iOS 5.0 berarti ini dapat dicapai menggunakan Blok lebih ringkas:
@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);
}];
Selalu ada F **** ng Block Syntax jika Anda lupa sintaks Block Objective-C.
+ (void)sayHi:(void(^)(NSString *reply))callback;
tidak boleh+ (void)sayHi:(void(^)(NSString *))callback;
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;
(Catatan parameterTypes
tidak parameters
)
CallBack: Ada 4 jenis callback di Objective C
Jenis pemilih: Anda dapat melihat NSTimer, UIPangesture adalah contoh callback Selector. Digunakan untuk eksekusi kode yang sangat terbatas.
Jenis Delegasi : Umum dan paling banyak digunakan dalam kerangka Apple. UITableViewDelegate, NSNURLConnectionDelegate. Mereka biasanya digunakan untuk menunjukkan Mengunduh banyak gambar dari server secara asinkron dll.
Tolong beri tahu saya jika ada jawaban lain untuk itu. Saya akan menghargainya.