Apple released a message on October 20, 2014: From next year's February 1, apps submitted to the App Store must support 64-bit. The detailed message address is: https://developer.apple.com/news/?id=10202014a
How are we supposed to start getting our app to support 64-bit?
Basic knowledge
The A7 CPU from iphone 5S to the newly released iphone 6 (A8 CPU) has already supported the 64-bit ARM architecture. See Wikipedia for an introduction to 64-bit. There's a lot of talk about Apple using the A7,A8 chip, can you refer to the IPhone 6 Apple A8 chip to compare Apple A7 boost significantly? , what does the IPhone 5s equipped with the A7 processor 64-bit mean?
1.Xcode 5.0.1 start to support compiling binary for 32-bit and 64-bit
2. Support both 32-bit and 64-bit, we need to select the minimum deployment target for IOS 5.1.1
3.64-bit binary must be running on a CPU that supports 64-bit, and the minimum OS version requirement is 7.0.3
About architectures parameter issues in Xcode "Build Setting"
1.Architectures: The set of instructions you want to support. (The support instruction set is implemented by compiling the corresponding binary packets, and if there are multiple supported instruction sets, the packets containing multiple instruction set codes will be compiled, resulting in a large package that is eventually compiled.) )
2.Valid architectures: The set of instructions that will be compiled. (Valid architectures and architecture the intersection of two collections is the version generated by the final compilation)
3.Build Active Architecture only: Compiles only the set of instructions that are applicable to the current device (if this parameter is set to Yes, using iphone 6 debugging, then a binary that is eventually generated that supports the ARM64 instruction set. General in debug mode set to Yes,release to No)
The following reference is given to the instruction set:
Armv8/arm64:iphone 6 (Plus), IPhone 5s, ipad Air (2), Retina ipad Mini (2,3)
Armv7s:iphone 5, IPhone 5c, IPad 4
Armv7:iphone 3GS, iphone 4, iphone 4s, IPod 3g/4g/5g, ipad, ipad 2, ipad 3, ipad Mini
Armv6:iphone, IPhone 3G, IPod 1g/2g
For support 64-bit, we can set architectures as standard architectures, on the latest Xcode 6, which includes ARMV7 and arm64.
Get apps to support 32-bit and 64-bit basic steps
1. Make sure that the Xcode version number >=5.0.1
2. Update project settings, minimum deployment target >= 5.1.1
3. Change architectures to standard architectures (include 64-bit)
4. Run the test code, resolve the compilation warnings and errors, and make changes to the appropriate location against this document or the Official document 64-bit Transition Guide for Cocoa touch. (The compiler can't tell us everything)
5. Test on the real 64-bit machine.
6. Use instruments to view memory usage issues.
Major changes in 64-bit
The 64-bit runtime environment and the 32-bit runtime environment are mainly the following two points different:
Changes in data types
Changes on the method call
Changes in data types
The integer data type changes as follows:
For the concept of byte alignment, refer to the following link: C-byte alignment
The floating-point type is changed as follows:
Changes in data types can have these effects on our programs:
1. Increased memory pressure
Conversion of 2.64-bit to 32-bit data
3. The calculation may produce different results
4. When a value is copied from a large data type to a small data type, the data may be truncated. (Nsinteger-int)
Changes on the method call
32-bit-based CPUs and CPUs based on 64-bit have different numbers of registers, and there are different protocols on the method calls. So 32-bit and 64-bit are different at the assembly level. If we do not use assembler programming in the program, the invocation protocol is seldom encountered.
How to write a robust 64-bit code
According to the above changes, the official document 64-bit Transition Guide for Cocoa Touch gives the following 7 steps:
1. Do not assign long integers to integer int (data loss is caused on 64-bit)
2. Do not assign pointer type pointer to integer int (64-bit causes address data loss)
3. Watch out for numerical calculations (mask calculation, unsigned integer and signed integer simultaneous use, etc.)
4. Be aware of the changes to the Alignment method
Conversion of data between 5.32-bit to 64-bit (user data passed through the network may exist in both 32-bit and 64-bit environments)
6. Rewrite the assembly code
7. Do not force conversions prior to variable parameter methods and immutable parameter methods
In the LLVM compiler, enumeration types can also define the size of the enumeration. When we assign enumeration values to a variable in use, the appropriate data type should be used.
Do not assign pointer type pointer to integer int
12345678 |
int a = 5; int *c = &a; /* 32-bit下正常,64-bit下错误。最新的Xcode6.0编译提示警告:‘Cast to int* for smaller integer type int‘*/ int *d = (int *)((int)c + 4); /* 正确, 指针可以直接增加*/ int *d = c + 1; |
If we must convert the pointer to an integer, we can change the above code to:
12 |
/* 32-bit和64-bit都正常。*/ int *d = (int *)((uintptr_t)c + 4); |
View uintptr_t defined as typedef unsigned long uintptr_t;
Keep data types consistent
When the method is used, the arguments, parameters, and assignments need to be kept in the same data type. In particular, there are several types of correct use in the iOS app:
Long
Nsinteger
Cfindex
size_t
Under 32-bit and 64-bit, both fpos_t and off_t are data sizes of bits, and never point them to int integers.
12345678910111213 |
long Performcalculation (void); int c = performcalculation (); // error 64-bit data will be intercepted long y = performcalculation (); // correct int Performanothercalculation (int input); LONG I = LONG_MAX; int x = performcalculation (i); // error int returnmax () {      return LONG_MAX;  // error |
Common data type conversion problems in cocoa
Nsinteger: There are separate definitions under 32-bit and 64-bit:
12345 |
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 typedef long NSInteger; #else typedef int NSInteger; #endif |
We should never assume that Nsinteger and int are the same size, and the following examples need to be noted in use:
1. When using NSNumber object conversion
2. When using Nscoder codec, if the Nsinteger code is encoded under the 64-bit device, the Nsinteger is decoded under the 32-bit device. If the size of the value exceeds 32-bit at the time of decoding, there will be an exception
Some constants defined in the 3.Famework using Nsinteger
CGFloat: As with Nsinteger, there are different definitions.
1234567 |
typedef CGFLOAT_TYPE CGFloat; #if defined(__LP64__) && __LP64__ # define CGFLOAT_TYPE double #else # define CGFLOAT_TYPE float #endif |
Here's a demonstration of the error:
12345 |
CGFloat value = 200.0; CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &value); //64-bit下出现错误 CGFloat value = 200.0; CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &value); //正确 |
Numerical calculation of integral type
The sign bit extension for C language can be referenced as: sign bit extension
We look directly at the example:
123456789 |
int a = -2; unsigned int b = 1; long c = a + b; long long d = c; printf( "%lld\n" , d); |
Problem: This code runs under 32-bit as expected, with a output of-1 (0xFFFFFFFF). The result of running under 64-bit is: 4294967295 (0X00000000FFFFFFFF).
Cause: The addition of a signed value and an unsigned value of the same precision is unsigned. This unsigned result is converted to a higher-precision value with a 0 extension.
Solution: Change variable b to grow integer long
Use the appropriate data size when creating data structures
C99 provides a built-in data type that guarantees consistent data size, even if the underlying hardware structure is different. In some cases, we know that the data is a fixed size or that a particular variable has a limited range of values. At this point, we should choose a specific type to avoid wasting memory.
Types are as follows:
Never use malloc to request a specific memory size for a variable, instead use sizeof to get the size of the variable or struct.
Also we need to be aware of modifying the formatted string to support both 32-bit and 64-bit.
Careful handling of methods and method pointers
12345678 |
int fixedFunction(int a, int b); int variadicFunction(int a, ...); int main { int value2 = fixedFunction(5,5); int value1 = variadicFunction(5,5); } |
In both of these methods, the data of the parameter is read with the same instruction under 32-bit, but on 64-bit, it is compiled with a completely different protocol.
If you pass a method pointer in your code, you should ensure that the protocol for the method invocation is consistent. Never convert a variable parameter method into a fixed parameter.
1234 |
int MyFunction(int a, int b, ...); int (*action)(int, int, int) = (int (*)(int, int, int)) MyFunction; action(1,2,3); // 错误示范 |
The compiler does not prompt for warnings or errors, and does not expose problems in the emulator. Before you publish your app, be sure to test it with a real machine.
Summarize
During the support 64-bit process, the project project should be fully checked according to the 7 steps provided in the Apple documentation. If the project involves a lot of C or C + + code, be more cautious in supporting 64-bit.
After writing this note, I think I need to revisit the basics of C. XD, by the way, prayed for a third-party library in the project hurriedly updated to support 64-bit, Amitabha.
PS: Find the static library that does not support arm64. -name *.a-exec lipo-info "{}" \;
How iOS Works Support 64-bit