Как выполнять функции обратного вызова в Objective-C?
Я просто хотел бы увидеть несколько завершенных примеров и должен это понять.
источник
Как выполнять функции обратного вызова в Objective-C?
Я просто хотел бы увидеть несколько завершенных примеров и должен это понять.
Обычно обратные вызовы в цели 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 ([делегат responsedsToSelector: @selector (myClassWillDoSomething :)) {». В моем примере от делегата требуется реализовать оба метода.
Вместо неформального протокола вы также можете использовать формальный протокол, определенный с помощью @protocol. Если вы это сделаете, вы измените тип установщика делегата и переменную экземпляра на " id <MyClassDelegate>
" вместо просто " id
".
Кроме того, вы заметите, что делегат не сохраняется. Обычно это делается потому, что объект, который «владеет» экземплярами «MyClass», обычно также является делегатом. Если MyClass сохранит своего делегата, то будет цикл сохранения. В методе dealloc класса, который имеет экземпляр MyClass и является его делегатом, рекомендуется очистить ссылку на делегат, поскольку это слабый обратный указатель. В противном случае, если что-то поддерживает экземпляр MyClass, у вас будет висящий указатель.
Для полноты, поскольку StackOverflow RSS просто случайно воскресил для меня вопрос, другой (более новый) вариант - использовать блоки:
источник
Вот пример, который не раскрывает концепции делегатов и просто выполняет необработанный обратный вызов.
Обычно метод - [Foo doSomethingAndNotifyObject: withSelector:] будет асинхронным, что сделает обратный вызов более полезным, чем здесь.
источник
Чтобы поддерживать этот вопрос в актуальном состоянии, введение ARC в iOS 5.0 означает, что это может быть достигнуто с помощью блоков еще более кратко:
Всегда есть синтаксис F **** ng Block, если вы когда-нибудь забудете синтаксис Objective-C.
источник
+ (void)sayHi:(void(^)(NSString *reply))callback;
не+ (void)sayHi:(void(^)(NSString *))callback;
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;
(Обратите внимание, чтоparameterTypes
нетparameters
)Обратный вызов: в Objective C есть 4 типа обратного вызова
Тип селектора : вы можете видеть, что NSTimer, UIPangesture являются примерами обратного вызова селектора. Используется для очень ограниченного выполнения кода.
Тип делегата : общий и наиболее часто используемый в платформе Apple. Уитаблевиевделегате, NSNURLConnectionDelegate. Обычно они используются для демонстрации асинхронной загрузки множества изображений с сервера и т. Д.
Пожалуйста, позвольте мне ответить на этот вопрос. Я буду признателен.
источник