Ios 在SDK中Swizzling NSDictionary初始值设定项

Ios 在SDK中Swizzling NSDictionary初始值设定项,ios,objective-c,runtime,method-swizzling,Ios,Objective C,Runtime,Method Swizzling,因此,我计划像其他人一样为NSDictionary创建一个安全的init函数,但由于我是SDK开发人员: 我想为它添加一个开关,用户可以决定是否打开它 我不想用Category来实现它 所以我创建了一个名为“AlDictionarySafeffunction.h”的全新类,它有两个函数,第一个是switch函数,如下所示: +(void)enableSafeFunction{ [ALSwizzlingHelper swizzleSelector:@selector(initWithO

因此,我计划像其他人一样为NSDictionary创建一个安全的init函数,但由于我是SDK开发人员:

  • 我想为它添加一个开关,用户可以决定是否打开它

  • 我不想用Category来实现它

所以我创建了一个名为“AlDictionarySafeffunction.h”的全新类,它有两个函数,第一个是switch函数,如下所示:

+(void)enableSafeFunction{
    [ALSwizzlingHelper swizzleSelector:@selector(initWithObjects:forKeys:count:)
                           ofClass:NSClassFromString(@"__NSPlaceholderDictionary")
              withSwizzledSelector:@selector(safeInitWithObjects:forKeys:count:)
                           ofClass:[ALDictionarySafeFunction class]];
}
-(instancetype)safeInitWithObjects:(const id _Nonnull __unsafe_unretained *)objects forKeys:(const id _Nonnull __unsafe_unretained *)keys count:(NSUInteger)cnt {
    BOOL containNilObject = NO;
    for (NSUInteger i = 0; i < cnt; i++) {
        if (objects[i] == nil) {
            containNilObject = YES;
            NSLog(@"There is a nil object(key: %@)", keys[i]);
        }
    }
    if (containNilObject) {
        //Do something to make sure that it won't cause a crash even it has some nil value
    }

    //There is the problem, next line
    [self safeInitWithObjects:objects forKeys:keys count:cnt];
}
ALSwizzlingHelper可以帮助我切换两个函数

第二个是safe init函数,如下所示:

+(void)enableSafeFunction{
    [ALSwizzlingHelper swizzleSelector:@selector(initWithObjects:forKeys:count:)
                           ofClass:NSClassFromString(@"__NSPlaceholderDictionary")
              withSwizzledSelector:@selector(safeInitWithObjects:forKeys:count:)
                           ofClass:[ALDictionarySafeFunction class]];
}
-(instancetype)safeInitWithObjects:(const id _Nonnull __unsafe_unretained *)objects forKeys:(const id _Nonnull __unsafe_unretained *)keys count:(NSUInteger)cnt {
    BOOL containNilObject = NO;
    for (NSUInteger i = 0; i < cnt; i++) {
        if (objects[i] == nil) {
            containNilObject = YES;
            NSLog(@"There is a nil object(key: %@)", keys[i]);
        }
    }
    if (containNilObject) {
        //Do something to make sure that it won't cause a crash even it has some nil value
    }

    //There is the problem, next line
    [self safeInitWithObjects:objects forKeys:keys count:cnt];
}
-(instancetype)safeInitWithObjects:(常量id(非空)(不安全)(未恢复)*)对象分叉(常量id(非空)(不安全)(未恢复)*)键计数:(nsInteger)cnt{
BOOL containNilObject=否;
对于(整数i=0;i
对于正常情况(在类别中编写swizzled方法),我需要像我编写的那样调用原始方法

但问题是我不能在这里这样做,因为“self”对象是“\uuu NSPlaceholderDictionary”的实例,而“\uu NSPlaceholderDictionary”类没有实例方法“safeInitWithObjects:forKeys:count:”

那我该怎么办

有办法做到吗


如有任何建议,我们将不胜感激。

请详细说明您为什么不想使用该类别?为什么不在
NSDictionary
的类别中声明
safeInitWithObjects:forKeys:count:
,并保留其余的实现?请注意,它不会解决所有问题,因为
NSDictionary
是类群集,但在提供任何答案之前,我想先了解一下您的动机。@BorisVerebsky 1我不想强迫用户添加“链接器标志”(-ObjC);2由于我有一个开关,所以它不会自动打开,类别是没有必要的;3我不想在类中添加任何代码,如果我使用Category,它会产生一些影响。您能详细说明一下为什么不想使用Category吗?为什么不在
NSDictionary
的类别中声明
safeInitWithObjects:forKeys:count:
,并保留其余的实现?请注意,它不会解决所有问题,因为
NSDictionary
是类群集,但在提供任何答案之前,我想先了解一下您的动机。@BorisVerebsky 1我不想强迫用户添加“链接器标志”(-ObjC);2由于我有一个开关,所以它不会自动打开,类别是没有必要的;3我不想在类中添加任何代码,如果我使用Category,它将产生一些影响。