Al pasar a Mac desde iOS en el desarrollo de Objective-C, NSIntegers dan errores de coincidencia de tipos

I've been working on an iOS project for some time now, and I've recently decided to port the code to a Mac project. Because I've chosen to use NSInteger in my code, and NSInteger is a environment-dependent typecast, it means that my variables are different types on the iOS and Mac apps.

When I run the test suite on the Mac, all my STAssertEquals calls fail with the error "Type mismatch --" because the types don't match:

NSInteger foo = 1;
STAssertEquals(foo, 1, nil); // Test fails!!

Typecasting my scalars seems to work, but this seems really messy:

NSInteger foo = 1;
STAssertEquals(foo, (NSInteger)1, nil); // Succeeds, but is ugly!!

Am I missing something here? I'm starting to suspect that the decision to use NSIntegers was a poor choice.

Update: Perhaps este artículo is related. It seems to support typecasting scalars.

preguntado el 01 de febrero de 12 a las 03:02

1 Respuestas

Your use of NSInteger is probably the right choice, but it does cause some issues with STAssertEquals.

STAssertEquals fails if the two objects have different Codificaciones de tipo Objective-C

Solo 1 will be interpreted by the C compiler as a (signed int), which has type encoding "i".

These macros would also fail:

unsigned u = 1;
STAssertEquals(u, 1, nil); // Fails because u is type "I" (unsigned int) and 1 is type "i" (int)

char c = 1;
STAssertEquals(c, 1, nil); // Fails because c is type "c" (signed char) and 1 is type "i" (signed int)

To make the compiler use a different type for 1, you would add a suffix such as 1U for (unsigned int), 1UL for (unsigned long) or 1L for (long).

NSInteger is defined to be the same size as pointers, which is dependent on the device architecture. On 32-bit Mac OS X and iOS, NSInteger is type (signed int), or "i". On 64-bit Mac OS X, it is type long, or "q". (64-bit Mac OS X is a LP64 architecture, which means that Longs and Pointers are both 64-bits wide)

Thus, the left side of your STAssertEquals is a "q", whereas the right side is "i", causing the type mismatch.

Your solution of using (NSInteger) 1 seems to accurately represent what you want - test an NSInteger variable against an NSInteger constant of value 1.

Respondido 01 Feb 12, 08:02

I would assume the following idea would almost certainly bad, but I figured I'd ask: Is there a way to force the compiler to treat untyped scalars such as "1" as NSIntegers? - Brent Traut

I don't believe so. The compiler will promote a significantly large integer constant to a (signed long) or (signed long long), but I don't believe there is a way to get this behavior for free (even if there was, you probably wouldn't want to do that :) ) - iccir

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.