Objective-C'de geri arama işlevleri nasıl gerçekleştirilir?
Sadece tamamlanmış bazı örnekler görmek istiyorum ve bunu anlamalıyım.
Objective-C'de geri arama işlevleri nasıl gerçekleştirilir?
Sadece tamamlanmış bazı örnekler görmek istiyorum ve bunu anlamalıyım.
Yanıtlar:
Normalde, C hedefindeki geri aramalar delegelerle yapılır. İşte özel bir temsilci uygulamasına bir örnek;
Başlık dosyası:
@interface MyClass : NSObject {
id delegate;
}
- (void)setDelegate:(id)delegate;
- (void)doSomething;
@end
@interface NSObject(MyDelegateMethods)
- (void)myClassWillDoSomething:(MyClass *)myClass;
- (void)myClassDidDoSomething:(MyClass *)myClass;
@end
Uygulama (.m) Dosyası
@implementation MyClass
- (void)setDelegate:(id)aDelegate {
delegate = aDelegate; /// Not retained
}
- (void)doSomething {
[delegate myClassWillDoSomething:self];
/* DO SOMETHING */
[delegate myClassDidDoSomething:self];
}
@end
Bu, genel yaklaşımı göstermektedir. NSObject üzerinde, geri arama yöntemlerinizin adlarını bildiren bir kategori oluşturursunuz. NSObject aslında bu yöntemleri uygulamaz. Bu tür kategoriye gayri resmi protokol denir, sadece birçok nesnenin bu yöntemleri uygulayabileceğini söylüyorsunuz. Seçicinin tip imzasını bildirmenin bir yolu.
Daha sonra, "MyClass" ın temsilcisi olacak bir nesneniz var ve MyClass, uygun şekilde temsilci üzerindeki temsilci yöntemlerini çağırıyor. Temsilci geri aramalarınız isteğe bağlıysa, onları genellikle gönderim sitesinde "if ([delegate responsesToSelector: @selector (myClassWillDoSomething :)) {" gibi bir şeyle koruyacaksınız. Örneğimde, temsilcinin her iki yöntemi de uygulaması gerekir.
Resmi olmayan bir protokol yerine, @protocol ile tanımlanan resmi bir protokolü de kullanabilirsiniz. Bunu yaparsanız, temsilci belirleyicinin türünü ve örnek değişkenini id <MyClassDelegate>
yalnızca " id
" yerine " " olarak değiştirirsiniz.
Ayrıca, temsilcinin alıkonulmadığını fark edeceksiniz. Bu genellikle yapılır çünkü "MyClass" örneklerine "sahip" olan nesne aynı zamanda temsilci de olur. MyClass temsilcisini elinde tutarsa, o zaman bir saklama döngüsü olacaktır. MyClass örneğine sahip bir sınıfın dealloc yönteminde iyi bir fikirdir ve zayıf bir arka işaretçi olduğu için bu temsilci başvurusunu temizlemek için temsilcisidir. Aksi takdirde, MyClass örneğini canlı tutan bir şey varsa, sarkan bir işaretçiniz olur.
Eksiksizlik açısından, StackOverflow RSS soruyu benim için rastgele yeniden dirilttiğinden, diğer (daha yeni) seçenek blokları kullanmaktır:
@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);
}];
Temsilcilerin kavramlarını dışarıda tutan ve sadece ham bir geri arama yapan bir örnek.
@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
Tipik olarak - [Foo doSomethingAndNotifyObject: withSelector:] yöntemi, geri aramayı burada olduğundan daha kullanışlı hale getirecek şekilde zaman uyumsuz olacaktır.
Bu soruyu güncel tutmak için, iOS 5.0'ın ARC'yi tanıtması, bunun Blocks kullanılarak daha da kısaca elde edilebileceği anlamına geliyor :
@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'nin Blok sözdizimini unutursanız her zaman F **** ng Blok Sözdizimi vardır .
+ (void)sayHi:(void(^)(NSString *reply))callback;
değil+ (void)sayHi:(void(^)(NSString *))callback;
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;
(Not parameterTypes
değil parameters
)
CallBack: Objective C'de 4 tür geri arama vardır
Seçici türü : NSTimer, UIPangesture'ın Selector geri aramasının örnekleri olduğunu görebilirsiniz. Çok sınırlı kod yürütülmesi için kullanılır.
Temsilci Türü : Yaygın ve en çok Apple çerçevesinde kullanılır. UITableViewDelegate, NSNURLConnectionDelegate. Genellikle birçok görüntünün sunucudan eşzamansız olarak indirilmesini vb. Göstermek için kullanılırlar.
Lütfen başka bir cevap varsa bana izin verin. Takdir edeceğim.