I’ve been crying by this pit these days.

Let’s start with the problem.

1. The return value was released for no apparent reason

So when you do the Router, the ViewController that comes back, push, and Xcode tells you self is nil. Black question mark. JPGCopy the code

The solution is to determine whether the current class is a Swift class (including “.”) and Retain it once if so

const char * returnType = [signature methodReturnType];
if (self.isSwift && returnValue && strcmp(returnType, @encode(id)) == 0){
    CFRetain((__bridge CFTypeRef)returnValue);
}
Copy the code

In 10.3.1 11.4 12.4 13.3 simulator test, the objects can be destroyed normally.

2. Run The Times EXC_BAD_INSTRUCTION????

It worked fine on iOS13, and then on 10, 11, 12, it all crashed. I almost lost my mind.Copy the code

I still have a long way to go before this problem is solved.

1. Why did it crash? No problem on 13.

2. Try performSelector: withObject, oh my god, will collapse.

3. Try not to send a reference. Ah, no problem.

4. Will not be released as return value, try double pointer. It won’t work. It’ll still blow up

5. The key value of the dictionary is String

6. It seems that the Value of NSDictionary must inherit from NSObject. Let the model inherit from NSObject, 🐂🍺.

7. You need to inherit all models from NSObject, which is a headache and follows the Hashable protocol. Get an ArgumentWrapper. Each dictionary value is wrapped in a Wrapper.

8. When writing the demo, I found that the second problem was caused by the failure of parameter type conversion. It’s in the unit tests of the demo.

conclusion

Of course, the final conclusion is that iOS13, which follows Hashale’s class, can convert dynamic calls to AnyHashable, whereas iOS13 doesn’t. If called directly, 10-13 can be converted to AnyHashable.

So when using it, it’s important to pay attention to the method parameter types. Don’t be like me. You almost cried.

If you’re interested, you can download NSInvocationDemo and play with it in unit tests.