After all, still come. Apple has issued an ultimatum to support the 64-bit:
As we announced in October, beginning February 1, new IOS apps submitted to the APP Store must include 64-bit support and is built with the IOS 8 SDK. Beginning June 1, app updates would also need to follow the same requirements.
The adaptation that should have been done has finally begun, and the 64-bit CPU has run a 32-bit program for so long. The previous period of time the company project completed the 64-bit package, this is not so complicated by the numerous non-standard old code stirring not light, summed up a few tip mutual encouragement.
Tips
Reject basic data types and implicit conversions
The first is the basic type, such as the following 4 types in the 32-bit and 64-bit, respectively, how long?
1234 |
size_t s1 = sizeof(int); size_t s2 = sizeof(long); size_t s3 = sizeof(float); size_t s4 = sizeof(double); |
32-bit under: 4, 4, 4, 8;64-bit: 4, 8, 4, 8
(PS: This result with the compiler, for other platforms may not necessarily)
Their length changes may not be our expectation of doubling the length of the 64-bit, so the code for sizeof appears in the program to see two more eyes. And, unless you know exactly what you're doing, you should use the following type instead of the base type:
These are the types defined in the SDK, and most of the time we are dealing with the SDK APIs, which can be used to reduce the impact of type conversions a lot.
Let's say the following code:
1234 |
NSArray *items = @[@1, @2, @3]; for (int i = -1; i < items.count; i++) { NSLog(@ "%d" , i); } |
As a result, the For loop does not go in at once.
The count of the array is of type Nsuinteger, and 1 is implicitly converted to Nsuinteger when compared to a large number:
1234 |
(lldb) p i (int) $0 = -1 (lldb) p (NSUInteger)i (NSUInteger) $1 = 18446744073709551615 |
This has nothing to do with 64-bit, to illustrate, this implicit conversion also needs to be careful, be aware of all the operations associated with this variable (assignment, comparison, conversion)
The old-fashioned for loop can be considered written as:
1 |
for (NSUInteger index = 0; index < items.count; index++) {} |
Of course, array traversal is more recommended with for-in or block versions, and comparisons between them can be reviewed in this article.
Using the new enumeration
Similar to the above, enumerations should use the new version of the notation:
123456 |
typedef NS_ENUM(NSInteger, UIViewAnimationCurve) { UIViewAnimationCurveEaseInOut, UIViewAnimationCurveEaseIn, UIViewAnimationCurveEaseOut, UIViewAnimationCurveLinear }; |
Not only can you specify a type for the enumeration value, but the compiler will also give a warning when assigning the wrong type, and there is no reason to use this notation.
Replace format string
When adapting to the 64-bit, did you encounter the following disgusting notation:
12 |
NSArray *items = @[@1, @2, @3]; NSLog(@ "数组元素个数:%lu" , (unsigned long)items.count); |
In general, use NSNumber's @ syntax sugar to solve:
12 |
NSArray *items = @[@1, @2, @3]; NSLog(@ "数组元素个数:%@" , @(items.count)); |
Similarly, int to string can also:
12 |
NSInteger i = 10086; NSString *string = @(i).stringValue; |
Of course, this format does not apply if you need to%.2f.
BOOL under the 64-bit
32-bit, BOOL is defined as signed char, and the result of @encode (BOOL) is ' C '
64-bit, BOOL is defined as BOOL, @encode (BOOL) result is ' B '
The more intuitive explanation is:
1234 |
(lldb) p/t (signed char)7 (BOOL) $0 = 0b00000111 (YES) (lldb) p/t (bool)7 (bool) $1 = 0b00000001 (YES) |
The 32-bit version of BOOL includes the possibility of 256 values and also causes some pits, as this article says. and 64-bit only 0 (NO), 1 (YES) two possible, finally to bool name.
Do not take the ISA pointer directly
The compiler has disabled this use by default, the ISA pointer is the address of class under 32 bits, but with bits mask under 64 bits to remove the real address, if you really need to, use the runtime's Object_getclass and Object_setclass methods. For a 64-bit explanation of ISA, you can read this article
Resolve third-party Lib dependencies and Lipo commands
In the form of the source code in the project of the third-party LIB, as long as the target plus arm64 compile the good.
The disgusting thing is that the static libraries (. A) or the framework, which are dragged directly into the project, need to be re-searched for the package that supports 64-bit. This time can see which is already unmanned maintenance of LIB, it is a substitute for a replacement (for example, I can not find the whole network of the project used in an audio library of the 64-bit package, finally found on a buddy's GitHub, crying to give a star--)
Print supported schemas for mach-o files
How to see if an executable file supports 64-bit?
Use the Lipo-info command, for example, to see Uikit supported schemas:
123 |
// 当前在Xcode Frameworks目录 sunnyxx$ lipo -info UIKit.framework/UIKit Architectures in the fat file: UIKit.framework/UIKit are: arm64 armv7s |
To see more detailed information you can use Lipo-detailed_info:
12345678910111213141516 |
sunnyxx$ lipo -detailed_info UIKit.framework/UIKit
Fat header
in
: UIKit.framework/UIKit
fat_magic 0xcafebabe
nfat_arch 2
architecture arm64
cputype CPU_TYPE_ARM64
cpusubtype CPU_SUBTYPE_ARM64_ALL
offset 4096
size 16822272
align 2^12 (4096)
architecture armv7s
cputype CPU_TYPE_ARM
cpusubtype CPU_SUBTYPE_ARM_V7S
offset 16826368
size 14499840
align 2^12 (4096)
|
Of course, you can also use the file command:
1234 |
sunnyxx$ file UIKit.framework/UIKit UIKit.framework/UIKit: Mach-O universal binary with 2 architectures UIKit.framework/UIKit ( for architecture arm64):Mach-O 64-bit dynamically linked shared library UIKit.framework/UIKit ( for architecture armv7s):Mach-O dynamically linked shared library arm |
The above command applies to the Mach-o file, the static library. A file, the. A file in the framework, and the executable file of your app can be printed down to see.
Merging packages with multiple schemas
If we have mylib-32.a and mylib-64.a, you can use the lipo-create command to merge:
1 |
sunnyxx$ lipo -create MyLib-32.a MyLib-64.a -output MyLib.a |
Will the package become larger after 64-bit support?
Will, support 64-bit, more than a arm64 architecture, in theory, each architecture a set of instructions, but compared to the original will be much more difficult to say, we have increased by about 50%, and heard that will increase by one times.
A lib contains a lot of architecture, will it hit the last bag?
No, if Lib has armv7, armv7s, arm64, i386 architecture, and target architecture chooses armv7s, arm64, then only the binary code of the two schemas specified by link from Lib, The code in the other schemas does not link to the final executable; in turn, a Lib needs to link normally in the emulator environment, as well as to include instructions for the i386 architecture.
Checklist
Finally, make a list of the points of note in the official documentation:
Do not turn the pointer strongly into an integer
Unified data types are used throughout the program
It is important to pay attention to the operation of different types of integers.
When you need a fixed-length variable, use a fixed-length type such as int32_t, int64_t
Do not write dead size when using malloc
Use a formatted string that can fit two schemas at the same time
Note Function and function pointers (type conversions and mutable parameters)
Do not directly access the OBJECTIVE-C pointer (ISA)
Using the built-in synchronization primitives (primitives)
Do not hardcode the virtual memory page size
Go Position Independent
References
https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/ Introduction/introduction.html#//apple_ref/doc/uid/tp40013501-ch1-sw1
Http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html
http://www.bignerdranch.com/blog/64-bit-smorgasbord/
http://www.bignerdranch.com/blog/bools-sharp-corners/
iOS engineering adaptation 64-bit experience sharing (GO)