如何覆盖包含块的objC中的方法?

时间:2015-10-06 14:32:11

标签: ios objective-c push-notification override

我知道如何覆盖Objective-C中的方法。我按照以下方式进行,并且工作正常。问题是,当原始方法包含块时,我不知道该怎么做。如果您能修复/添加我的代码,我将不胜感激。

在下面的代码中,我已经使用我不知道如何覆盖的块注释了该方法。仅供参考:我正在覆盖与推送通知服务相关的代码。

    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 个答案:

答案 0 :(得分: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)
{

}