“Writing High Quality OC Code” has been successfully completed chapter one, two, three, four, five, six, eight! Attach a link: Objective-c code for iOS (1) — Objective C code for iOS (2) — Objective C code for iOS (3) — Interface and API design Objective-c code (5) — Memory management mechanism (6) — Block column iOS Writing high quality Objective-C code for iOS (GCD


There are currently two official languages being promoted for iOS development: Objective-C and Swift. Today, we’ll help you become more familiar with Objective-C and talk about how to write high-quality OC code.

The origins of Objective-C

The origins of Objective-C predate Java by more than a decade. Java was introduced in 1995, while Objective-C has been around since the 1980s. ~

Objective-c (OC) evolved from Smalltalk, the granddaddy of message-passing languages.

  • Messaging? Yes! Introduced our first Key of the day. OC is similar to, but very different from, object-oriented languages such as C++ and Java. Why do you say that? The first topic to be introduced is that OC uses messaging rather than C++ and Java use function call mechanisms.
// Objective-c: messaging Object *obj = [Object new]; [obj performWith:parameter1 and:parameter2]; // C++:functionCalling (function call) Object *obj = new Object; obj->perform(parameter1, parameter2);Copy the code

Difference: Messaging: the code executed by the runtime is determined by the runtime environment (Runtime) function calls: the code executed by the runtime is determined by the compiler

In simple terms, the OC always looks for the actual method to call at run time. The compiler doesn’t care what type of object the message is received from. The object that receives the message works at run time, a process called dynamic binding. Most other object-oriented languages, on the other hand, look up the “virtual table” at runtime to find out which methods are being executed. Or a superclass method? .


OC is a superset of C, and if you are familiar with C, much of what you know in C still applies when writing OC code. So, the second Key of the day: Pointers.

Pointers in OC are mainly used to indicate objects. The basic syntax of OC is similar to that of C.

  • For example: declare a string
NSString *str1 = @"QiShare";
Copy the code

A variable named str1, of type NSString*, is declared. Is a pointer to NSString.

  • Wrong examples:
NSString str2;
Copy the code

Error: Interface type cannot be statically allocated Object Cannot be allocated to stack space

OC objects cannot be allocated on the stack, because the memory occupied by OC objects is allocated to the heap space, and the programmer controls its allocation of memory. The temporary base data in the stack is controlled by the compiler.

  • Here’s another typical example:
xxxClass *Qi = [[xxxClass alloc] init];
xxxClass *Share = Qi;
Copy the code

There are two xxxClass Pointers allocated on the stack: Qi and Share point to the same memory address in the heap.

Memory structure, as shown below:

For objects allocated in the heap, memory must be managed by the developer. Pointers allocated to stack space are automatically cleaned up when their stack frame pops up.

OC abstracts heap memory management into a mechanism: ARC(Automatic Reference Counting). In OC, there is no need to use malloc and free to allocate or free memory occupied by objects. OC abstracts this work into a memory management architecture in a run-time environment, which we call “reference counting.” There will be a blog post on ARC mechanics later

In order to reduce the compile time, the.h file should introduce as few other header files as possible.

Consider the “forward declaration” class in the.h file if necessary.

@class QiShareClass;

@interface xxx : xxx

// ...

@end
Copy the code

Reintroduce the class in the.m file

#import "QiShareClass.h"/ /...Copy the code

At the same time, the forward declaration solves the problem that two classes may reference each other. Such as:

  • Qi. H
#import "Share.h"
Copy the code
  • Share. H
#import "Qi.h"
Copy the code

When parsing “qi.h”, the compiler finds “share. h” and then injects itself” qi.h “. This creates circular references. This will result in one of the two classes not compiling correctly. Recommendation: If protocols are used, wrap them in a separate header file if necessary. Not only does this reduce compilation time, but it also avoids the problem of circular references.

Third, use more literal grammar, less equivalent methods

  • Benefits: Concise and easy to read, improving code readability and maintainability
  • Limitations: When creating arrays or dictionaries with literals, values cannot have nil, otherwise an exception will be thrown.

For Example:

// Literal string NSString * STR = @"QiShare"; NSNumber *num = @(1); NSNumber *floatNum = @ (1.0); int x = 5;floatY = 3.14; NSNumber *num = @(x * y); // Array NSArray *animals = @[@"cat"The @"dog"The @"tiger"The @"monkey"]; NSString *cat = animals[0]; NSDictionary *qiShareDic = @{@"englishName": @"QiShare"The @"chineseName": @"Odd Share"}];
NSString *englishName = qiShareDic[@"englishName"];
NSString *chineseName = qiShareDic[@"chineseName"];
Copy the code
  • Note: Objects created using literal syntax are immutable objects by default. If you need a mutable object, perform a mutableCopy step
NSMutableString *mutableStr = [@"QiShare" mutableCopy];
Copy the code

4. Use more type constants and less #define preprocessing instructions

  • Benefits: Defined constants contain type information, are immutable, and are readable.
  • The value defined by #define is just a string substitution before compilation and does not contain type information. And if constant values are accidentally redefined, the compiler does not raise any warnings ⚠️, resulting in inconsistent constant values.

For Example:

# define ANIMATION_DURATION 0.5// Replace static const NSTimeInterval kAnimationDuration = 0.5; // qishare. h extern const NSTimeInterval QiShareAnimationDuration; // qishare. m const NSTimeInterval QiShareAnimationDuration = 0.3;Copy the code

Enumeration represents status, option and status code

  • The readability of the code is enhanced by enumerations representing the state of the state machine, the options passed to the method, and the status code equivalents.
  • If multiple choices are possible, the option value is defined as a power of 2. Facilitate the underlying conversion to binary storage.
  • Using the NS_ENUM and NS_OPTIONS macros to define enumeration types can indicate the underlying data types. It’s up to the developer, not the compiler. For Example:
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
Copy the code

Finally, a special thanks to Effective Objective-C 2.0, chapter 1