Frequently asked questions in iOS interviews – Basics

I will sum up some learning videos and books on iOS in the “Code Non Style” public account, which can be obtained by partners in need

If you want to discuss and learn the underlying principles of iOS together, you can add me Q_2336684744. Welcome to study and communicate with us

OC Memory Management – Basic with MRC

Overview of Memory Management

  1. Memory management The memory is used to store data.
  2. How to store data in memory. Declare a variable and store the data in it.
  3. How to free up occupied memory when data is no longer in use.
  4. Five regions in memory
    1. Stack: local variable, which is immediately reclaimed by the system when the scope of the local variable is executed.
    2. Heap: OC object, the space requested by the C function. We need to do our own memory management
    3. BSS segment: uninitialized global variables, static variables. Once initialized, it is reclaimed and stored in the data segment.
    4. Data segment: initialized global variables, static variables. It is not recycled until the end of the program.
    5. Code snippet: Code. Data stored in the code snippet is automatically reclaimed when the program terminates.

The collection of data stored in stacks, BSS segments, data segments, and code segments is done automatically by the system without our intervention.

OC objects allocated in the heap definitely need to be recycled.

IPhone memory mechanism, will be 40M and 45M occupied memory warning, reached 120M will directly flash back. OC objects stored in the heap are not automatically reclaimed until the end of the program.

Scope of memory management:

We only need to manage the collection of OC objects stored in the heap. The collection of data in other areas is automatically managed by the system and does not need to be managed by us.

When should objects be reclaimed?

When someone uses this object, it should never be reclaimed. It can only be reclaimed if no one else is using the object.

Reference counter action

1). Each object has a property called a retainCount reference counter of type unsigned long that is 8 bytes long. The reference counter is used to keep track of how many people currently use the object. By default, an object is created. The default value of the reference counter for this object is 1.

2). When the object is used by one more person, the reference counter value of the object should be set to +1 to represent the object used by one more person.

3). When the object is used by one less person, the reference counter value of this object should be set to -1 to represent the object is used by one less person.

4). When the reference counter of this object turns to 0, it means that this object is not used, and the system will automatically reclaim this object.

How to operate reference counters.

1). When you send a retain message to the object, the reference counter of the object is incremented by 1.

2). Send a release message to the object, and the reference counter of the object will be reduced by 1, only when one less person uses the object.

3). Send a retainCount message to the object to fetch the value of the object’s reference counter.

4). When the reference counter of the object becomes 0, the object will be immediately reclaimed by the system. When the object is reclaimed, the dealloc method of the object will be automatically called.

Classification of memory management

MRC: Manual Reference Counting – Manual memory management – When one more person uses the object, the programmer is required to manually send a retain message and when one less person uses the object, the programmer is required to manually send a relase message. ARC: Automatic Reference Counting – Automatic memory management – The system automatically sends a retain relase message where appropriate.

How to understand MRC

1). Create a new object whose reference counter defaults to 1.

2). When the reference counter of the object becomes 0, the object is immediately reclaimed and the dealloc method is automatically called.

3). Send a retain message to the object and its reference counter will +1.

4). Send a release message to the object, not to reclaim the object, but to make the reference counter of the object -1. When the value of the reference counter of the object changes to 0, the object will be immediately reclaimed by the system.

MRC overwrites the dealloc method specification: must call the parent class dealloc method, and must be placed in the last line of code.

Key points and principles of memory management

1). To create an object, match a release.

2).retain and release times should match.

3). Whoever retains and releases the retain will be responsible for relase.

4). Retain only when one more person uses it and release only when one less person uses it. A retain should match a release and must be balanced.

5). Retain Release dealloc methods cannot be called under ARC.

What is a wild pointer

C language wild pointer: define a pointer variable, no initialization, the value of the pointer variable is a garbage value, pointing to a random space, then this pointer is called wild pointer. Wild Pointers in OC: Pointers to objects that have been reclaimed are called wild Pointers.

Object and the nature of memory reclamation

Asking for a variable is essentially asking the system for a specified number of bytes of space that the system will not allocate to anyone else. When a variable is reclaimed, the byte space that represents the variable can be allocated to someone else in the system. But the data stored in byte space is still there. Object reclamation refers to the fact that the space occupied by objects can be allocated to others. The object data is still there when the space it occupies is not allocated to someone else.

What are zombie objects

An object that has been freed but whose space has not been allocated to anyone else is called a zombie object. When we access zombie objects through wild Pointers, if the space occupied by zombie objects has not been allocated to others, then it is ok, and when the space occupied by zombie objects is allocated to others, it is absolutely not. So as long as the object is a zombie object, access is not allowed anyway. Xcode provides a real-time inspection mechanism for zombie objects. You can turn this mechanism on. Once turned on, an error will be reported whenever a zombie object is accessed, regardless of whether space is allocated.

Why not turn on zombie object detection by default?

Once zombie object detection is enabled, every time an object is accessed, it will first check whether the object is a zombie object. This is extremely performance consuming. Enable Zombie object detection: Product -> Scheme -> EditScheme -> Diagnostict -> Zombie Objects

How to avoid zombie object error when using wild pointer to access zombie object?

When a pointer is called wild, set the value of the pointer to nil. When a pointer is nil, calls to methods (including dot syntax) from that pointer will not get an error, but will get an error by directly accessing the property ->.

How to understand memory leaks

An object that is not collected in time is not collected at the time of collection and remains in memory until the end of the program. Memory leaks for a single object:

1). There is object creation without corresponding relase.

2). Retain count does not match relase count.

3). Assign Pointers to nil when inappropriate.

4). Improper retain of passed objects in a method.

How setter methods are written when property is 1 OC object

Assigning the incoming object to the property of the current object represents one more person to use the incoming object, so we should send a retain message to the incoming object before assigning the value. When this attribute is assigned multiple times, it means that the old object will be used by one less person and the new object will be used by one more person. Relase the old object to retain the new object. Relase should be in dealloc when the current object is destroyed and one less person is using the object to which the attribute points. Code writing:

     - (void)setCar:(Car *)car
     {
         if(_car ! = car) { [_car release]; _car = [car retain]; - (void)dealloc {[_car release]; [super delloc]; }Copy the code

@ the role of the property

1). Automatically generate private attributes.

2). Automatically generates a declaration of getter setter methods for this property.

3). Automatically generate the implementation of getter setter methods for this property.

@ property parameters

1).@property can take parameters. @property(parameter 1, parameter 2, parameter 3……) Data type name;

2). Introduce the four groups of parameters of @property.

Two parameters related to multithreading are nonatomic – atomic

Assign-retain, the parameter associated with the implementation of the generated setter method

Parameter related to generating read-only and read/write readonly – readwrite

Getter-setter parameter associated with the generated getter setter method name

3). Describes parameters related to multithreading.

Atomic: The default. If you write atomic, the generated setter code will be locked with a thread-safe lock. Features: Safe, but inefficient. Nonatomic: Code that writes setter methods generated at nonatomic time does not add thread-safe locks. Features: Insecure, but efficient.

4). Parameters associated with the implementation of the generated setter method.

Assign: The default. The implementation of the generated setter method is direct assignment. Retain: The implementation of the generated setter method is standard MRC memory management code, which determines whether the old and new objects are the same object, if not release the old retain new. Retain is used when the property is of type OC object type. Assign is used when the attribute type is non-OC. Note: the retain argument, which generates the standard setter method as standard MRC memory management code, does not automatically generate relase code in dealloc. So, you have to manually release in dealloc yourself.

5). With the generation of read-only, read and write encapsulation.

Readwrite: Default value that generates getter setters at the same time. Readonly: only getters are generated, not setters

6). Generate parameters related to getter and setter method names.

By default, getter setter methods generated by @ Property have the most standard names. We can also specify the name of the method generated by @property as an argument.

Getter = Name of the getter method used to specify the name of the getter method generated by @property. Setter = Setter method name Specifies the name of the setter method generated by @property. Notice that setter methods take arguments so we have to add a colon. Note: If you change the name of the generated method using getter setters, the compiler converts to code that calls the modified name when using dot syntax.

Note: Do not change the name of the setter method under any circumstances, because the generated name is standard by default. When the property is of type 1 BOOL, you can change the getter name to start with is to make the code more readable.

7). Only one group of parameters can be used, and the sequence of parameters can be arbitrary.

The difference between @class and #import

  1. Cyclic references occur when two classes contain each other, resulting in infinite recursion and failure to compile.
  2. Solution: Instead of importing the other side’s header using #import, use@ the class name of the class;To indicate that this is a class, so that the compiler can be told that this is a class without importing the other header file. In the.m file, add #import to the header file.
  3. Difference 1). #import copies the contents of the specified file to the place where the instruction is written. 2). @class does not copy anything, it just tells the compiler that this is a class so that the compiler knows it is a class at compile time.

OC Memory management – ARC and classification

  1. When an automatic release pool is destroyed, the release method of all objects stored in the automatic release pool is automatically called. Fixed problem: When you create an object and store it in the auto-release pool, you don’t need to manually relase the object, because when the pool is destroyed, the relase of all objects in the pool will be automatically called. Benefits of automatic release pooling: Objects created are stored in the automatic release pool without the need to write releases.

  2. How to create autoreleasepool @autoreleasepool

    } // The parentheses represent the range of the autorelease pool.Copy the code
  3. Calling an object’s AutoRelease method from an autorelease pool puts the object into the current autorelease pool. The autorealse method returns the object itself. @autoreleasepool{ Person *p1 = [[[Person alloc] init] autorelease]; } When the auto-release pool completes, a release message is immediately sent for the objects in the auto-release pool.

  4. Use attention

1). An object is stored in the autorelease pool only if the object’s autorelease method is called in the autorelease pool. The object will not be stored in the autorelease pool if the object’s creation code is written in the autorelease pool without calling the object’s autorelease method.

2). Objects can be created outside the autorelease pool. From the autorelease pool, the object can be stored in the autorelease pool by calling the autoRelease method of the object.

3). Autorelease cannot be stored in the autorelease pool outside. When the autorelease pool ends, just send a release message to the object stored in the autorelease pool instead of destroying the object.

4). If you call the autoRelease method of the same object more than once in the autorelease pool, the object will be stored in the autorelease pool more than once. At the end of the auto-release pool, multiple release messages will be sent for the object, which will cause a zombie object error. Therefore, in an autoreleasE1 pool, only autoreleasE1 times, the object is only put once, otherwise there will be a wild pointer error.

5). If the release method of an object stored in the automatic release pool is called, the release method of the object will be called again when the automatic release pool ends. This is where wild pointer operations are possible. You can also call the retain method on objects stored in the automatic release pool.

6). Adding an object to the auto release pool does not increase the reference counter of the object by 1. Omit the release that creates the object match

7). The autorelease pool can nest the calling object’s autoRelease method, which adds the object to the current autorelease pool and only sends a release message to the object when the current autorelease pool ends.

  1. Autorelease specification

An object created using a class method requires that the object has already been autoreleased by the method. Thus, when we call a class method to create an object in the auto-release pool, the object is automatically added to the auto-release pool. Using object methods does not automatically autorelease.

Provides a class method to get an object quickly. Specification A. This class method begins with the class name. If there are no arguments, the class name is WithXX: b. + (instanceType)person {return [[[self alloc] init] autoRelease; } This way, we call the class method directly. @autoreleasepool {Person *p1 = [Person]; @autoreleasepool {Person *p1 = [Person]; // This p1 object is already passed by autorelase. The p1 object is stored in the current autorelease pool without calling autorelase. It will send a release message for the P1 object stored in it.Copy the code

Classes in Apple’s framework also follow this specification. Objects created by class methods are already autoReleased. Therefore, we must comply with the specification, and the objects returned by class methods must also be passed by Autorealse. We usually create an object by calling a class method to create an object that is already autoReleased.

Summary of the ARC

  1. Arc-automatic Reference Counting is an Automatic Reference Counting system. The system automatically helps us calculate the value of the object’s reference counter. Using ARC in your application is very simple, just write the code as usual, but never retain, release, autorelease and never manually call dealloc. This is the basic principle of ARC. It is important to note that ARC is a compiler mechanism. When ARC is enabled, the compiler automatically inserts retain, release, and autorelase code in the appropriate places to automatically count references to objects.
  2. The nature of when an object is released by ARC: The object is automatically released when its reference counter reaches zero. Representation: As long as there is no strong pointer to the object, the object is immediately recycled.
  3. Strong and weak Pointers Strong Pointers: By default, one pointer is declared, and this pointer is a strong pointer. We can also use __strong to declare that this is a strong pointer. Person *p1; // This is a strong pointer. Pointers are always 1 strong by default. __strong Person *p2; // This is also a strong pointer. Declaration of strong Pointers using __strong to display. Weak Pointers: Pointers with an __weak identifier are called weak Pointers. It doesn’t make any difference whether it’s a strong pointer or a weak pointer, they’re both Pointers, they can be used to store addresses, they can be used to access members of objects. The only difference is that in ARC mode, they are used as a baseline for recycling objects. If an object does not have any strongly typed pointer to it, the object is immediately and automatically freed

How is memory managed for individual objects under ARC

In ARC, when an object has no strong pointer to it, the object is immediately reclaimed.

1). When an object does not have any strong pointer to it, the object is immediately recycled.

int main(int argc, const char * argv[]) { @autoreleasepool { Person *p1 = [Person new]; //p1 is a strong pointer. Person *p2 = p1; // P2 is also a strong pointer. Both p1 and p2 point to the Person object. NSLog(@"-- -- -- -- -- -"); }// the p1 pointer is reclaimed, and the p2 pointer is reclaimed. Then the Person object doesn't have any strong Pointers to it. This is where the object is collected.return 0;
    }
Copy the code

2). Assign all strong Pointers to objects to nil. The object is immediately reclaimed.

int main(int argc, const char * argv[]) { @autoreleasepool { Person *p1 = [Person new]; // Because we said that every pointer variable is a strong pointer variable by default. // The Person object is not pointed to by any pointer, so the Person object is not pointed to by any pointer. The Person object is released here. NSLog(@"------"); } return 0; } There is no strong pointer to the object. All strong Pointers to objects are assigned nilCopy the code

ARC releases an object if there is no strong pointer to it, and if there is a weak pointer to it, the object will be released.

int main(int argc, Const char * argv[]) {@autoreleasepool {// Use __strong to indicate p1 is strongly typed. __strong Person *p1 = [[Person alloc] init]; __weak Person *p2 = p1; __weak Person *p2 = p1; P1 = nil; p1 = nil; p1 = nil; } return 0;} return 0;} return 0; }Copy the code

3). Most important 1 point: can not create an object with a weak pointer to store the object pointer, so that the newly created object, there is no strong pointer to it, it will be recycled.

int main(int argc, Const char * argv[]) {@autoreleasepool {// Create an object and assign the address of the object to a weak pointer. // Create an object that has no strong pointer Person *p1 = [[Person alloc] init]; } return 0; }Copy the code

4). In ARC, weak Pointers to objects are automatically set to nil when they are reclaimed.

 Person *p1 = [Person new];
 __weak Person p2 = p1;
 p1 = nil;
 [p2 sayHi];
Copy the code

Focus under ARC mechanism

When a class attribute is an OC object, should the attribute be declared strongly or weakly typed? Obviously, it should be a strongly typed one. The arguments, strong and weak, control whether @property generates a strong or weak private property.

@property(nonatomic,strong)Car *car; @property(nonatomic,weak)Car * Car; @property(nonatomic,weak)Car * Car; The generated private attribute _car is weakly typed.Copy the code

If no, the default value is strong.

1). In ARC, if the attribute type is OC object type, strong is used in most scenarios. 2). Under ARC, if the attribute type is not of OC object type, use Assign. 3). Strong and weak are assigned when the attribute type is OC. Assign is used when the attribute type is not OC. 4). In ARC, when two objects reference each other, using strong on both sides will leak memory. Solution: Use strong on one end and weak on the other. 5). Use the -fno-objc-arc command to set some classes to use MRC. 6). The whole MRC program can be converted into ARC program; Edit -> Convert ->To Objective-C ARC (Not recommended)

Classification – the function of category and points to note

A few points to note when classifying a class into multiple modules:

  1. Classification can only add methods, not attributes

  2. You can write @property in a class but it doesn’t automatically generate private properties, it doesn’t automatically generate implementations of getter setters, it just generates declarations of getter setters. So you have to write your own getter and setter declarations, and if you want to define your own property, that property has to be in this class.

  3. The class’s real private properties (defined in the class’s @implementation) cannot be accessed directly in the class’s method implementation, but the class’s getter setter can be called to access the properties.

  4. When a class has a method with the same name as the class, the method of the class is called first, even if no header file is introduced. If the same method exists in multiple classes, the last compiled class is called first.

  5. When do you need to use classification when a class has a lot of methods and a lot of clutter, when a class is bloated. At this time, we can use classification to divide the class into multiple modules and write the methods with similar functions in the same module.

  6. Informal Protocols – Writing classes for the system’s native classes is called an informal protocol.

ARC mechanism and garbage collection mechanism

Garbage collection mechanism – GC: While the program is running, there is a thing called garbage collector that continuously scans the heap for objects that are not being used.

ARC: Instead of runtime, operations like retain are inserted in place at compile time. When enough code is inserted to leave the object unused, the reference counter is zero and the object is reclaimed.


I will sum up some learning videos and books on iOS in the “Code Non Style” public account, which can be obtained by partners in need.