Search code examples
objective-cdebuggingxcode4

Passing NSNumber* to NSString* expected-parameter does not cause compiler warning / error


Any way to fix this?

I changed my a signature of a function to pass NSString object instead of NSNumber object. Except I have some instances that still pass the old NSNumber object. It's hard to track down because the compiler doesn't display ANY errors or warnings for this. I tried deleting the DerivedData folder. Doesn't help.

I also tried to do Analyze, that doesn't catch those problems either.

I know I can do an NSAssert check to make sure that the incoming parameter type is proper, but this seems backwards. This should be something the compiler picks up and warns me.

Any suggestions?

- (void) test:(NSString *)par;

calling

NSString *str = (NSString *)[array objectAtIndex:0];

Except the object is NSNumber, so technically it casts an NSNumber to NSString. Debugger sees it as NSNumber, so not sure why it's being allowed in the first place.


Solution

  • Any way to fix this?

    not easily. assertions (as you mentioned) are a starting point.

    I changed my a signature of a function to pass NSString object instead of NSNumber object.

    objc doesn't work that way - objc objects just pass addresses through their arguments/variables at execution.

    there is no explicit type conversion provided by the language when typecasting; in case that was your expectation.

    nor does objc use a typesafe cast to determine whether the argument is of the type it is being cast to.

    Except I have some instances that still pass the old NSNumber object. It's hard to track down because the compiler doesn't display ANY errors or warnings for this. I tried deleting the DerivedData folder. Doesn't help.

    you get NSNumbers because that is what exists in the array.

    I also tried to do Analyze, that doesn't catch those problems either.

    it's a very dynamic language, and that is how it was designed.

    the analyzer cannot pick up those issues or look for them because the check must be performed at runtime.

    also, it's commonplace to pass objc objects around and use them dynamically (using respondsToSelector: and isKindOfClass:).

    I know I can do an NSAssert check to make sure that the incoming parameter type is proper, but this seems backwards. This should be something the compiler picks up and warns me.

    I use assertions and have written several checks and types to return type safety where i want it.

    i know of no public lib for this - you're probably on your own to implement the checks you want. creating a simple header for these checks and implementing them is easy enough.

    Except the object is NSNumber, so technically it casts an NSNumber to NSString. Debugger sees it as NSNumber, so not sure why it's being allowed in the first place.

    for objc variables, the debugger evaluates the object at the address to determine its type rather than using the type declared by the variable.