Как переопределить метод в objC, который включает в себя блок?
Я знаю, как переопределить метод в Objective-C. Я делаю это как следует, и все работает нормально. Проблема в том, что я не знаю, как это сделать, когда оригинальный метод включает в себя блок. Буду признателен, если вы сможете исправить / добавить мой код ниже.
В приведенном ниже коде я закомментировал метод с блоком, который я не знаю, как переопределить. К вашему сведению: я переопределяю код, связанный со службой push-уведомлений.
id delegate = [[UIApplication sharedApplication] delegate];
Class objectClass = object_getClass(delegate);
NSString *newClassName = [NSString stringWithFormat:@"Custom_%@", NSStringFromClass(objectClass)];
Class modDelegate = NSClassFromString(newClassName);
if (modDelegate == nil)
{
modDelegate = objc_allocateClassPair(objectClass, [newClassName UTF8String], 0);
SEL selectorToOverride4 = @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:);
SEL selectorToOverride5 = @selector(application:didFailToRegisterForRemoteNotificationsWithError:);
SEL selectorToOverride6 = @selector(application:didReceiveRemoteNotification:);
//SEL selectorToOverride7 = @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:);
// get the info on the method we're going to override
Method m4 = class_getInstanceMethod(objectClass, selectorToOverride4);
Method m5 = class_getInstanceMethod(objectClass, selectorToOverride5);
Method m6 = class_getInstanceMethod(objectClass, selectorToOverride6);
//Method m7 = class_getInstanceMethod(objectClass, selectorToOverride7);
// add the method to the new class
class_addMethod(modDelegate, selectorToOverride4, (IMP)didRegisterSuccess, method_getTypeEncoding(m4));
class_addMethod(modDelegate, selectorToOverride5, (IMP)didRegisterFailure, method_getTypeEncoding(m5));
class_addMethod(modDelegate, selectorToOverride6, (IMP)didReceiveRemoteNotification, method_getTypeEncoding(m6));
//class_addMethod(modDelegate, selectorToOverride7, (IMP)didReceiveRemoteNotificationFetchCompletionHandler, method_getTypeEncoding(m7));
// register the new class with the runtime
objc_registerClassPair(modDelegate);
}
// change the class of the object
object_setClass(delegate, modDelegate);
void didRegisterSuccess(id self, SEL _cmd, UIApplication *application, NSData *deviceToken)
{
[base didRegisterSuccess:application deviceToken:deviceToken];
}
void didRegisterFailure(id self, SEL _cmd, UIApplication *application, NSError *error)
{
[base didRegisterFailure:application error:error];
}
void didReceiveRemoteNotification(id self, SEL _cmd, UIApplication *application, NSDictionary *userInfo)
{
[base didReceiveRemoteNotification:application userInfo:userInfo];
}
/*
void didReceiveRemoteNotificationFetchCompletionHandler(id self, SEL _cmd, UIApplication *application, NSDictionary *userInfo, void(^)(UIBackgroundFetchResult)handler)
{
}
*/
1 ответ
Решение
Блоки - это просто объекты Objective-C, так что вы можете просто использовать id
Тип блока:
void didReceiveRemoteNotificationFetchCompletionHandler(id self, SEL _cmd, UIApplication *application, NSDictionary *userInfo, id handler)
{
}
Или вы можете определить свой собственный тип для вашего блока и использовать его:
typedef void (^YourBlockType)(UIBackgroundFetchResult);
void didReceiveRemoteNotificationFetchCompletionHandler(id self, SEL _cmd, UIApplication *application, NSDictionary *userInfo, YourBlockType handler)
{
}