Write high-quality OC code--------familiar with Objective-c

Source: Internet
Author: User
Tags constant data structures processing instruction
1th: Understanding the origins of Objective-c language
1. Message Structure of OBJECTIVE-C
OBJECTIVE-C uses "message structure" instead of "function call". The key difference between a message structure and a function call is that the language in which the message structure is used is determined by the runtime, and the language used by the function call is determined by the compiler. If the function call is polymorphic, then at runtime it is necessary to follow the "virtual method table" to find out which function implementation should be performed. The language of the message structure, whether polymorphic or not, always checks the method to be executed at run time. In fact, the compiler doesn't even care what type of object the message is received from. An object problem that receives a message is also handled at run time, and its process is called "dynamic binding."
2. Objective-c Run-Time library
The important work of objective-c is done by the runtime library, not by the compiler. The runtime library provides objective-c object-oriented capabilities, and all the data structures and functions required to use Objective-c's object-oriented features are provided by the runtime library. For example, the run-time component contains all the memory management methods.
3. OBJECTIVE-C Memory model
The objects in the objective-c are indicated by pointers. To declare a variable to refer to an object, you can use the following syntax: NSString * somestr = @ "the string"; This syntax is basically a copy of the C language, which declares a variable named somestring, whose type is Nsstr ing*. In other words, this variable is a pointer to NSString. All objects of the Objective-c language must be declared this way, because the object's memory is always allocated in the heap space and is never allocated on the stack.           The Objective-c object cannot be allocated in the stack. The following code:
NSString * Somestr = @ "the string";
NSString * anothrestr = SOMESTR;
There is only one nsstring instance, but two variables point to this instance. Two variables are nsstring*, which indicates that the current "stack frame" is allocated two memory, each block of memory can be the size of a pointer (4 bytes on the 32-bit architecture of the computer, 64-bit computer is 8 bytes). These two pieces of memory are the same value, which is the memory address of the NSString instance.
The memory allocated in the heap must be managed directly, and the memory allocated on the stack to hold the variable is automatically cleaned up when its stack frame pops up.
The objective-c will be abstracted out of memory management. You do not need to allocate or free memory with malloc and No. The OBJECTIVE-C Runtime Environment abstracts This part of the work into a set of memory management architectures called reference counts.
If you only save non-object types such as int, float, double, char, and so on, you usually use the cgrect structure. CGRect is a C language structure. Saved on the stack. This structure is used throughout the system framework, because performance is affected if you use the Objective-c object instead. Creating objects also requires additional overhead, such as allocation and heap memory, as compared to creating structs.

2nd: In the header file of the class, refer to the other header files as few as 1. The timing of the introduction of the header file is postponed as far as possible, only when there is a need to introduce it, which reduces the header file grooming required by the user of the class. Shorten compilation time.
2. Forward declaration solves the problem of two class circular references, when two classes are circular references. Using #import instead of # include does not cause a dead loop, but it means that one of the two classes cannot be compiled correctly.
3. It is sometimes necessary to refer to other header files in the header file. If you write a class that inherits from a superclass, you must introduce a header file that defines that superclass. Similarly, if you want to declare that the class you are writing inherits from a superclass, it must be fully defined and cannot use forward declaration. A forward declaration can only tell the compiler that there is a protocol, and the compiler knows the method defined in the protocol. So the protocol is usually declared in a separate file (except for the proxy protocol, which is meaningless if the proxy protocol is declared separately).
3rd: More use of literal grammar, less use of the equivalent of the method
The literal syntax is actually just a "sugar-coated grammar" whose effect is equivalent to the regular syntax but is more convenient for developers to use. The "icing syntax" makes the program easier to read and reduces the chance of code errors.
Points:
1. You should use literal syntax to create strings, numbers, arrays, dictionaries.         This is more concise than the usual method of creating such objects.         2. The element that corresponds to the key in the array subscript or dictionary should be accessed by removing the label operation. 3. When an array or dictionary is created with literal syntax, an exception is thrown if there is nil in the value. Therefore, it is important to ensure that the value does not contain nil.
Limitations of literal syntax:
1. The object created must belong to the foundation framework. To create a custom subclass instance, you must use non-literal syntax.
2, the literal syntax created by the string, array, dictionary objects are immutable. If you want a variable version of an object, you need to assign a value:
Nsmutablearray * mutable = [@[@1, @2, @3, @4] mutablecopy];

4th: Multi-use type constants, less # define preprocessing directives
Take the following preprocessing as an example:
#define ANIMATION_DURATION 0.3 1, preprocessing directives do not carry type information, type constants carry type information.
2, the pre-processing instruction scope is not clear, assuming that the directive is declared in a header file, then all the code that introduced the header file, its animation_duration will be replaced. 3. Even if someone has redefined the constant value, the compiler will not produce a warning, which will result in inconsistent constant values in the application.

In the implementation file, define "constants visible only within the compilation unit" static const nstimeinterval kanimationduration = 0.3;
Variables must be declared with both static and Const. The const ensures that the variable is immutable, and static means that the variable is visible only in the compilation unit where the variable is defined. If this variable is declared without static, the compiler creates an "external symbol" for it. If a variable with the same name is also declared in another compilation unit, the compiler will error. In fact, several variables are declared as static and const, so the compiler does not create symbols at all, but instead, it will replace all encountered variables with constant values, just like the # define preprocessing directives.   However, keep in mind that constants in this way have type information. Sometimes it is necessary to expose a constant externally. Such constants need to be placed in the global symbol table so that they can be used outside the compilation unit that defines the constant. It should be defined like this.

In the header file
extern NSString * Const eocstringconstant;

In the implementation file
NSString *const eocstringconstant =@ "VALUE";
This constant is to appear in the global symbol table, so its name should be separated, usually prefixed with the class name associated with it. In summary, do not use preprocessing directives to define constants, but compilers should be used to ensure that constants are correct.

5th: Enumeration uses the C++11 standard to revise some of the enumeration's attributes. One of the changes is that you can specify what type of "underlying data type" is used to hold the variables of the enumerated types. The advantage of this is that you can declare the enumeration variables forward. The enum type cannot be declared forward without specifying the underlying data type. Because the compiler does not know the size of the underlying data type, when using this enumeration type, it is not known exactly how much memory space should be allocated to the variable.
If the option passed to a method is expressed as an enumeration type, and multiple options can be used simultaneously, then each option value is defined as a power of 2 to be combined by a bitwise OR operation.
Use Ns_enum and Ns_options macros to define the enumeration type and indicate its underlying data type. Doing so ensures that the enumeration is implemented using the underlying data type chosen by the developer, rather than using the type chosen by the compiler.
Do not implement the default branch in a switch statement that handles enumeration types. In this case, after adding the new enumeration, the compiler will prompt the developer: The switch language does not handle all enumerations

   
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.