1

So I'm plan to create a safe init function for NSDictionary like someone else did, but as I'm a SDK developer:

  • I want add a switch for it, the user can decide if he want open it or not;

  • I don't want to use Category to implement it.

So I create a totally new class named "ALDictionarySafeFunction.h", it has two functions, the first one is the switch function, like this:

+(void)enableSafeFunction{
    [ALSwizzlingHelper swizzleSelector:@selector(initWithObjects:forKeys:count:)
                           ofClass:NSClassFromString(@"__NSPlaceholderDictionary")
              withSwizzledSelector:@selector(safeInitWithObjects:forKeys:count:)
                           ofClass:[ALDictionarySafeFunction class]];
}

The ALSwizzlingHelper can help me to swizzle two functions.

The second is the safe init function, like this:

-(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];
}

For the normal situation(Write the swizzled method in the Category), I need to do like I wrote to invoke the original method.

But the problem is I cannot do it here, because that the "self" object is the instance of “__NSPlaceholderDictionary”, and the "__NSPlaceholderDictionary" class doesn't have the instance method "safeInitWithObjects:forKeys:count:".

So what should I do?

Is there a way to make it?

Any advice will be appreciated.

Borys Verebskyi
  • 4,160
  • 6
  • 28
  • 42
Alanc Liu
  • 1,294
  • 10
  • 15
  • Could you elaborate why you don't want to use category? Why not to declare `safeInitWithObjects:forKeys:count:` in category for `NSDictionary`, and keep rest of the implementation? Note that it will not fix all the issues, cause `NSDictionary` is class cluster, but before providing any answer I would like to undertand your motivation first. – Borys Verebskyi Nov 12 '17 at 18:57
  • @BorisVerebsky 1 I don't want to force my user to add the 'linker flag'(-ObjC); 2 As I have a switch of it, so it will not turn on automatically, the category is not necessary; 3 I don't want to add any code to the class, it will make some influences anyway if I use Category. – Alanc Liu Nov 30 '17 at 01:51

0 Answers0