iOS Special Summary
After an application has been iterated over many iterations, what else can we do technically? The answer is to improve the overall quality of the code. In this respect, testing is also very important in addition to the refactoring we often shout.
The blogger recently gave our iOS client code a special test. Mainly from the conventional auxiliary testing, the code to clean up, find the code problems, and change them. The surprise is that this is a great help to improve the level of my Code. In fact, the quality of this set of code itself is very high, and very neat. This is mainly due to the strict code specification and pull request mechanism.
As for testing, apps often focus on functionality, including unit testing, using monkey to see whether the page behaves correctly on the interface, and so on. I used to ride a AspectJ + robotium. (This is Java) However, testing should cover code quality, performance detection, and so on.
Here is a diagram of my understanding of the test:
Along this map, we can start with static testing.
About analyze
Executing the product---analyze tool in Xcode, there is a coarse, thin, pointed arrow identifying the invocation logic.
This tool is mainly found in the code of the logic problem, itself can find a lot of problems. Actual application to the engineering code, the problems identified are mainly divided into the following four points:
For example, initialization assignment has not been used.
For example, the super statement was not called.
For example, variables that have never been used.
For example, logically wrong code. (This is very rare)
However, with respect to the resource file, the tool is not scanned. In addition, we can configure the tool in Xcode.
Clang Static Analyzer
The bottom of the analyze is actually the Clang Static Analyzer, which contains both ' shallow ' and ' deep ' shades of two modes.
Deep mode is much slower than shallow mode because of the cross-method control flow analysis and data flow analysis. (as in the previous picture)
Suggestions:
Turn on all of the analyzer's checks (by turning on all options in the "Static Analyzer" section of build setting)
In build setting, the build configuration for release opens "Analyzer during ' build '. (Really, be sure to do this-you won't remember to run the analyzer manually.) )
Set "Model of Analysis for ' Analyze '" in Build setting to shallow (faster)
Set the "Model of Analysis for" build in build setting to deep
But both of these are not good for a big project, and if you open the model of analysis for ' build ' in build setting and set it to shallow mode, it doesn't make sense to run it all at once.
Another idea is to run the ad hoc package automatically before the static analysis, is more reasonable can also be opened in Xcode. But we compiled the packaging with an automated tool that would skip this analysis when the server reads directly from GitHub rather than through Xcode.
It is a reasonable practice to run the Analyzer tool regularly. (e.g. every Friday) instead of build, release did it before. (Ask the other colleagues for advice)
At present, static analysis in the project has so few pieces of the problem: the first is the online copy over the algorithm. including encryption algorithm, fuzzy algorithm, 64-bit compilation algorithm and so on. There are some larger than, far less than, and arithmetic. Do not understand the place does not change.
Why not change it? Because I didn't see the logic problem. (or if you understand it, do not dare to change, afraid of the algorithm error.) )
Slender
Slender is a Mac software for image analytics for IOS. To import the project, you can find all unused resource. (Unused This software can also find redundant resources)
In addition, it also gives recommendations for all resource files. Includes your default x3, X2 image version, and so on.
Faux Pas
Surprise found in the accident. Faux Pas is an excellent static Error detection tool.
Slender found an unused resource, faux found the image that was used in the code but does not exist. (There are often a lot of measurements)
Some of the deprecated folders were even discovered.
Not only that, it has more than 100 error and warning rules. Includes the undefined user define runtime attributes (running on runtime). This is usually hard to see by the programmer's naked eye. Once you for the sake of the diagram of the xib directly in the dazzling technology, plus some key. However, when the code changes, delete a class, it is impossible to xib to delete the corresponding part.
There are also some code-specification issues.
For example, the text on the interface is not localized, there is still nslog output in release version, Nsphotolibraryusagedescription is undefined in info.plist, delegate is defined as strong type, and so on.
And some of the recommendations on the configuration.
Warning
Are you still reporting warning in your pods? You can block them using this method.
At the beginning of podfile add such a remark:
inhibit_all_warnings!
You can block the warning of all the code in the pods.
And then it's a pity that there is nothing to compile the warning. Note: The options for Xcode warning are not blocked in iOS. can only block a file, or the warning of a project. For example, we have blocked the code in the pods error. However, the system does not block warnings that are not code-level during the compilation process.
It is also not recommended to block such warnings, such as those caused by the 7.0 release of the Friends League. Now it is not supported by whether, 7.0 of users have many reasons, but the future may be solved. This should not be forgotten.
Leaks
Apple has integrated a performance testing tool called instruments. Using the leaks tool in instrument:
iOS memory leaks are few, mostly internal to the system, or in some libraries. We have no way of doing that. Measured down, the main leakage scene concentrated on the Uikeyboard. When I try a variety of click scenes, the system is most easily leaked when the frame.
If there is a leak in your code, they may focus on the quick slide listing when loading a large batch of images. In our application, most of these use the online open source mature library.
Where iOS might leak, my advice is to look backwards through known code specifications. such as misuse of the strong type of delegate, block does not use the weak self and so on.
Time Profiler
Where did all the time go? This tool can identify our most time-consuming operations and locate them in the code.
Indeed, an unreasonable time-consuming cycle was found in the actual use of the process.
(The black part on the right is a time-consuming operation, but not necessarily the wrong code)
Tools are just a matter of counting the time consumed, and more importantly, by the sensitivity of the code, the analysis locates the code that can be optimized. For example, there is a code like this.
There is a loop that uses an enumeration type when it is judged, but because the enumeration type does not get count, it writes dead loops 10 times.
But we can actually add type_max at the end of the enumeration type. This has the advantage of enumerating at switch time, and obtains the method that Nsarray obtains count.
Load time
Load time, the main look at different networks under the first page has no card death. The company WiFi condition on the real on-board test about 1.2s Nega loaded, and when the analog Edge network when the main line loads is still fast, no problem found.
There are two ways to view startup time. One is through the time detection tool above, the other is directly in the code to log. There are two ways to play log.
Say these two kinds of play separately:
Cfabsolutetime StartTime;
int main(int argc, Char * *argv) {
StartTime = cfabsolutetimegetcurrent();
// ...
}
- (BOOL)application:(uiapplication *)application Didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"launched in%f sec", cfabsolutetimegetcurrent() - StartTime) ;
});
// ...
}
This is the usual way to print. However, there are too many uncontrolled factors to start starting from main.
IOS App startup process
The framework of the loading process we are difficult to control, and the initialization of the font, status bar, user defaults, main nib, and so the process, we do not need to care. Of course, what you can do is keep them as small as possible without redundancy.
So, there is another way to keep track of the time you spend in didfinishlaunchingwithoptions. Here, you may have initialized a number of unnecessary third-party libraries and made several network requests. And these, we can all lazyload, let the program cold start as soon as possible.
Frame rate, etc.
How to display the frame rate label gracefully?
In Quartzcore.framework, there is a Cadisplaylink class. When each frame is rendered, the system invokes the selector in Cadisplaylink, which is a bit like a timer class, which is called 60 times a second by default.
The frame rate is stable for most of the time at 60fps, however there are two cases where it is not possible to invoke the callback method at a frequency of 60 times per second.
We can use the characteristics of this class to write the following code to display a screen frame rate label in real time.
Cadisplaylink DisplayLink = [cadisplaylink displaylinkwithtarget: Self selector :@selector(tick:)];
[_displaylink addtorunloop:[nsrunloop mainrunloop] formode: Nsrunloopcommonmodes];
- (void)tick:(cadisplaylink *)displayLink {
//...
self. Numberofframes+ +;
nstimeinterval Delta = displayLink. Timestamp - self. Lasttimestamp;
//Less than one second
if (Delta < 1) {
return;
}
cgfloat fps = self. Numberofframes / delta;
//update Label
....
}
The FPS value is the number of frames per second. The measured current pull refresh, or load list too fast, will fall very badly. And that's where the performance bottleneck lies.
After you've developed your IOS app, the next thing you need to do