What's New in Objective-C

Source: Internet
Author: User

Description

Note (Ray ):Part of the article from iOS 7 by Tutorials iOS 7Feast (omitted)

Objective-C Is the most important development tool for iOS and OSX apps. You can use third-party frameworks in other languages to develop apps, such as HTML & Javascript or C #. However, if you quickly write a superb and efficient sound source app, you need to make Objective-C.

Foundation Is one of the core frameworks you use to develop Objective-C applications.

As an iOS developer, it is very necessary to understand the latest Objective-C and Foundation features. You need to understand some important changes in iOS7.

In this article, you will quickly browse some new features in Objective-C and Foundation.

1. Modules (module)

The opportunity is good. You have already written one thousand times or more # import statements:

#import <UIKit/UIKit.h>#import <MapKit/MapKit.h>#import <iAd/iAd.h>

This syntax is traced back to the root of Objective-C: vanilla C. # The import Statement works in a similar way as the pre-processor command and the # include statement. The only difference is that # import does not import imported header files; it is a one-time processing.

When a # import command is run during preprocessing, the line is replaced with all the content of the imported header file. Pre-compilation will do this recursively, even if it may be a large number of header files.

The header file of UIKit, UIKit. h, contains all other header files contained in the UIKit framework. This means that you do not have to manually import the header files of each framework, such as UIViewController. h and UIView. h UIButton. h.

Are you curious about the size of the UIKit framework? By calculating the headers of all rows in all UIKit, you will find that it is equivalent to more than 11,000 lines of code!

In a standard iOS app, you will import the UIKit in most of your files, which means that each file will eventually be 11000 lines long. This is not ideal. More code means a longer Compilation Time.

1.1 Original solution: Pre-compile the header file (Original solution: Pre-compiled Headers)

Pre-compiled header files, or PCH files, try to solve this problem by providing the Code required for pre-calculation and caching in the pre-compilation phase. You may have read the stock PCH file generated by Xcode, as shown below:

#import <Availability.h>#ifndef __IPHONE_5_0#warning "This project uses features only available in iOS SDK 5.0 and later."#endif#ifdef __OBJC__    #import <UIKit/UIKit.h>    #import <Foundation/Foundation.h>#endif

If the targets of an app developed by developers is an SDK before iOS5, # warning will notify them. The header files of UIKit and Foundation umbrella are part of stockPCH. Because Foundation is used for every file in your application, and most of the files use UIKit. Therefore, these are good additions for PCH files so that you can pre-calculate and cache the compilation files of these files in your APP.

You may ask, "What's the problem ?" PCH has no technical problems, such as -- if it isn' t broke, don't fix it (don't fix it if there is no bad one ). However, you may miss out on many performance advantages due to a Easily maintained and highly optimized PCH file (you may miss the well-maintained on a host, performance advantages of highly optimized PCH files ). For example, you may use the Map Kit framework in several places, you will see how to increase the Compilation Time by adding the Map Kit umbrella header file or the Map Kit Class header file that you use to the PCH file.

We are all lazy developers, and no one has time to maintain the PCH file of the project we work on. That's whyModulesFeatures developed as LLVM.

Note:LLVM is a set of modular and reusable compilers and tool technologies bundled with Xcode. LLVM has several components: clang, native C, C ++, and Objective-C compilers, and LLDB are the best friends of native debugger-developers for oc developers.

1.2 New Solution: Module)

The first public appearance of Modules in Objective-C was a talk by Apple's Doug Gregor at the 2012 LLVM Developer Conference. This is a fascinating conversation and is strongly recommended to those interested in compilation. You can watch these videos online at http://llvm.org/devmtg/2012-11/#talk6.

The Modules encapsulation framework is cleaner than ever before. No longer requires preprocessing to replace all the content of the file with the # import command line by line. On the contrary, a module contains a framework to a self-contained block, which improves the compilation speed just like the pre-Compilation Method of PCH files. In addition, you do not need to declare the frameworks you want to use in the PCH file, and use Modules to easily increase the speed.

However, Modules is not the only one. I believe you will think of these steps when you use a new framework in an app for the first time, as shown below:

1. Add # import to the file using the framework

2. Use a framework to write code

3. Compile

4. Viewing Link errors

5. Think of the framework that forgets the link

6. Add the forgotten framework to the project.

7. recompile

Forgetting the link frame is a common mistake, but the Modules solution is very good.

A Modules not only tells the Compiler which header files constitute the Modules, but also tells the compiler what needs to be linked. This saves you the need to manually link the framework. Although this is a trivial matter, it is a good thing to make development easier.

1.3 How to Use Modules

Modules is quite simple to use. For existing projects, the first thing is to make this function take effect. You can find this option by searching Modules in Build Settings of the project, and change the Enable Modules option to YES, as shown in the following code:

This function is enabled for all new projects by default, but you should enable this function for all existing projects.

The Link Frameworks Automatically option can be used to enable or disable the automatic connection framework function, just as described in. There is another reason why you want to disable this function.

Once the Modules function is enabled, you can use it in your code. In this way, there is a slight change to the syntax used previously. Replace # import with @ import:

@import UIKit;@import MapKit;@import iAd;

It is also possible to import only the required parts of a framework. For example, if you only want to import the UIView, you can write it as follows:

@import UIKit.UIView;

Right-it's really that simple. Technically, you don't need to replace all # imports with @ import, because the compiler will implicitly convert them. However, it is a good habit to use New syntaxes as much as possible.

Before you are excited to start using Modules, unfortunately there is a small warning. The Modules of Xcode5 does not support your own or third-party frameworks. This is an unfortunate disadvantage. Nothing is perfect, even if it is Objective-C!

2. New return type-instancetype

Objective-C adds a new return type named instancetype. This is only used as the return type of the Objective-C method and a hint to the compiler. It implies that the return type of the method will be an instance of the class that the method belongs.

Note:This feature is not strict in iOS 7 and Xcode, but will be quietly added to the latest Clang over time. However, Xcode5 declared for the first time that Apple has used this in their framework. You can view more information on the official Clang page:

Why is instancetype used? Take a look at the following code:

NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil];NSLog(@"%i", d.count);

Although this is obviously incorrect, the compiler will not remind you of any errors. Compile it in Xcode4.6. You will see no warning, but this code is obviously wrong. This code can even run without exceptions, because both nsdicloud and NSArray instances can count accordingly.

This code is normal because of the powerful dynamic characteristics of Objective-C. This type is a guide to the compiler. The Count method is searched for at run time regardless of the class, which is exactly the same as the dictionary variable. In this case, the count method exists and the compiler believes it is correct. However, you will use NSDictionary methods that NSArray does not have later, such as objectAtIndex. First, he will not clearly identify the problem.

But What compiler did not point out that the instance returned by the + [NSArray arrayWithObjects:] method is not an NSDictionary instance? This method is declared as follows:

+ (id)arrayWithObjects:(id)firstObj, ...;

Note that the return type is id. The id type is an umbrella type that means any Objective-C class. It is not even a subclass of NSObject. The method does not return the type information, rather than the Objective-C class instance. This is useful. The compiler will not warn you when you implicitly convert the id to an exact type. For example, the above NSDictionary example. If a warning is generated, the id is useless.

But why is the return type of this method id? You can subclass this method and use it without any problems. To prove why, consider the following NSArray subclass:

@interface MyArray : NSArray@end
Now consider how to use your subclass in the following code:

MyArray *array = [MyArray arrayWithObjects:@(1), @(2), nil];
Now you should know why arrayWithObjects: The returned type must be id. For NSArray *, This subclass needs to be converted into necessary classes. This is where the new instancetype return type is used. If you look at the NSArray header file in iOS7SDK, you will notice that this method has changed to the following:

+ (instancetype)arrayWithObjects:(id)firstObj, ...;

The only difference is the return type. The new return type prompts that the compiler returns an instance of the class called by the method. So when arrayWithObjects is called as NSArray, the return type is NSArray *. When MyArray is called, the return type is MyArray *.

When the sub-type capability is successfully maintained, problems may occur when the id is used. If you use Xcode5 to compile the original code, you will see the following warning:

warning: incompatible pointer types initializing 'NSDictionary *' with an expression of type 'NSArray *' [-Wincompatible-pointer-types]NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil];

It is helpful. Now you have the opportunity to modify this problem to prevent the next crash.

The initialization method is candidate to use this new return type. Now, if you set the initialization method to return an incomplete type compiler, you are notified. However, it may implicitly convert the id to instancetype. You should still use instancetype, because it is better to be clear.

If you try to use instancetype as much as possible, it will become Apple's standard-you don't know how much time it will take for you to degugging in the future.

3. New Foundations

The next step is some new things of the Objective-C core development framework Foundation. It is difficult to develop Objective-C applications without Foundation, and all iOS Apps need to be used. Check the newly added content in the new iOS SDK.

The main improvement of Foundation is the network. (NSURLSession) there is a full chapter on iOS 7 by Tutorials. (Omitted)

The rest of the article shows the newly added and changed content of the Foundation.

3.1 NSArray

Try to access an Object in the NSArray instance. If the following table is out of bounds, an exception occurs. When using arrays as queues, you may frequently access the first or last element in the array. In the first-in-first-out queue (FIFO), you may need to POP elements from the front-end of the array. If the first-in-first-out queue (FILO) is used, the POP element from the end of the array is required.

However, when you access the first or last element of an array, you must be sure that it does not exceed the boundary of the array. If the array is empty, such access is often performed. This will lead to redundant code when calling objectAtIndex: no error is reported, as shown below:

NSMutableArray *queue = [NSMutableArray new];// ...if (queue.count > 0) {    id firstObject = [queue objectAtIndex:0];    // Use firstObject}// ...if (queue.count > 0) {    id lastObject = [queue objectAtIndex:(queue.count - 1)];    // Use lastObject}
To access the last element, you should use the NSArray method:

- (id)lastObject;
Objective-C developers should be happy. Now they have a method to access the first element of the array:

- (id)firstObject;

A simple method is always proven to be useful. You do not need to check whether the array is empty. You may have encountered a Crash caused by cross-border attacks. You can take a look at the following considerations:

Note:If you carefully read the NSArray header file, the firstObject has already appeared in iOS4.0 and is not available until iOS7. Therefore, you can obtain this method before iOS7, but you must declare this method firstObject in your own header file to tell the compiler that it does exist. This is not an advocate method. Apple has made this method public.

The previous code can be rewritten using these two methods, so you do not need to check the array length, as shown below:

NSMutableArray *queue = [NSMutableArray new];// ...id firstObject = [queue firstObject];// Use firstObjectid lastObject = [queue lastObject];// Use lastObject
3.2 NSData

Data is the most widely used thing in programming. NSData is a Foundation class that encapsulates original bytes and provides methods to manipulate these bytes, allowing you to read or write data from a file. However, a simple task Base64 encoding and decoding is not implemented by the native. It does not appear until iOS7.

Base64 is a set of Binary-to-text conversion solutions that provide binary data in ASCII format. These schemes are used to encode binary data for storage or to convert multimedia files into text data for transmission. This ensures data integrity during transmission. The most common use of Base64 encoding is to process email attachments or encode small images, which are part of the JSON returned through Web-based APIs.

Before iOS7, Base64 encoding and decoding must be implemented by yourself or use a third-party library. The typical Apple style is very easy to use now. There are four Base64 methods:

- (id)initWithBase64EncodedString:(NSString *)base64String       options:(NSDataBase64DecodingOptions)options;- (NSString *)base64EncodedStringWithOptions:      (NSDataBase64EncodingOptions)options; - (id)initWithBase64EncodedData:(NSData *)base64Data       options:(NSDataBase64DecodingOptions)options; - (NSData *)base64EncodedDataWithOptions:      (NSDataBase64EncodingOptions)options;
The first two methods process strings, and the last two methods process UTF-8-encoded data. These two pairs have the same functions, but sometimes one of them is more efficient than the other. If you want a Base64 encoded string and then write it into the file, you should use this pair of methods for UTF-8 encoding data. On the other hand, if you want to encode the string with Base64 and then use JSON, you should use another method. If you have implemented the Base64 encoding method, you can delete it because Apple has already implemented it for you. 3.3 NSTimer

NSTimers are often used to execute periodic tasks in apps. Although NSTimer is useful, it also produces problems. When several timers are in use, they may trigger intermittently. This means that the CPU is intermittently active. This is more efficient. When the CPU is changed, some tasks are executed and then sleep. To solve this problem, Apple adds a tolerance attribute to NSTimer to adapt to this behavior.

Tolerance provides the system with a guidance on how long the timer can delay after the schedule. To reduce the CPU load, the underlying system will collect these activities. The new attributes are as follows:

- (NSTimeInterval)tolerance;- (void)setTolerance:(NSTimeInterval)tolerance;
You may never need this attribute, but when you trigger several timers very closely, you may find it useful, when you use Instruments to detect CPU usage.

3.3 NSProgress

It is not often seen that the Foundation will add a new class completely. It is a stable framework. The main reason is that core classes are not frequently used. However, iOS7 provides a complete new class NSProgress.

In essence, NSProgress is used to generate progress reports through Objective-C code and separate the progress of each independent module. For example, you can execute several different tasks on some data, and then each task can manage its own progress and report it to its parent task.

3.3.1NSProgress Structure

The simplest way to use NSProgress is to report the progress of some task sets. For example, if you have 10 tasks executed, you can report the progress when each task is completed. The progress increases by % 10 when a task is completed. Then, use Key Value Observing (KVO) on the NSProgress instance to learn the progress of the instance. You can use this notification to update the progress bar or display an indicator text.

NSProgress has more functions. Apple makes the parent-child relationship more powerful. The structure of NSProgress is more like a mesh tree. Each NSProgress has one parent class and multiple child classes. Each instance has a total number of worker units executed. The current task will update the number of completed sub-tasks to report the current status. In this case, the parent class will be notified of the progress.

To reduce the transmission of NSProgress instances, each thread has its own NSProgress instance, and then the sub-instance can be directly created from this instance. Without this function, every task that wants to report progress has to be notified by parameters.

3.3.2 report progress

NSProgress is easy to use. Start with the following method:

+(NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount;

This method creates an NSProgress instance as a subclass of the current instance and initializes it with the total number of task units to be executed. For example, if the task loops through an array, you may use the number of arrays to initialize the NSProgress instance. For example:

NSArray*array = /* ... */; NSProgress*progress =    [NSProgressprogressWithTotalUnitCount:array.count]; [arrayenumerateObjectsUsingBlock:    ^(id obj, NSUInteger idx, BOOL *stop) {        // Perform an expensive operation onobj        progress.completedUnitCount = idx;    }];

As the iteration progresses, the above Code updates the NSProgress instance to reflect the current progress.

3.3.3 receive progress updates

You can get the task progress at any time using the following attributes:

@property(readonly) double fractionCompleted;

The return value ranges from 0 to 1, indicating the overall progress of the task. If no sub-instance is available, fractionCompleted simply splits the number of completed tasks by the total number of tasks.

Key Value Observing (KVO) is the best way to get the fractionCompleted Value to be changed. This is very simple. You only need to add an observer for the NSProgress fractionCompleted attribute. As shown below:

[_progressaddObserver:self           forKeyPath:@"fractionCompleted"              options:NSKeyValueObservingOptionNew               context:NULL];

Then override the KVO method to get the changes:

-(void)observeValueForKeyPath:(NSString *)keyPath                      ofObject:(id)object                        change:(NSDictionary*)change                       context:(void *)context{    if (object == _progress) {        // Handle new fractionCompleted value        return;    }     // Always call super, incase it uses KVOalso    [super observeValueForKeyPath:keyPath                         ofObject:object                           change:change                          context:context];}

In this method, you can change the value of fractionCompleted. For example, you may change the progress bar or prompt text.

Of course, it is important to remember to log out of KVO after processing.

[_progressremoveObserver:self              forKeyPath:@"fractionCompleted"                  context:NULL];

You must always log out. If you do not log out, the registered Object will be Crash when it is released. Therefore, if necessary, logout in dealloc serves as the final guarantee.

4. WhereTo Go From Here (what to do later)

(Omitted)

5. Original and Reference Links

Link: http://www.raywenderlich.com/49850/whats-new-in-objective-c-and-foundation-in-ios-7

Reference: http://www.onevcat.com/2013/06/new-in-xcode5-and-objc/

Http://www.longyiqi.com/blog/programming-languages/2012/04/05/at-import-objc/



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.