Summary of iOS classic interview questions - memory management

Summary of iOS classic interview questions - memory management

[[163414]]

I made a summary based on my own situation, and the answer is my summary. If there are any shortcomings in the answer, I hope to criticize and correct me as well as communicate with me. Thank you!

Memory Management

1. What is ARC?

ARC is automatic reference counting, which automatically adds retain/release when the program is compiled. When the object is created, retain count+1, when the object is released, count-1, when count=0, destroy the object. When the autoreleasepool object is added to the program, the system will automatically add the autorelease method, and if the object reference count is 0, it will be destroyed. So ARC was born to solve some of the problems of manual memory management in MRC.

Disadvantages of memory management under MRC:

  • When releasing a heap memory, first make sure that all pointers to this heap space are released. (Avoid premature release)
  • To release the heap space pointed to by the pointer, first determine which ones point to the same heap, and these pointers can only be released once. (Avoid releasing multiple times and causing memory leaks)
  • When operating in a modular way, an object may be created and used by multiple modules, and it is not certain who will release it first.
  • When operating in multiple threads, it is uncertain which thread will be used up first.

Although ARC brings us many benefits in programming, it may also cause memory leaks. For example, in the following two situations:

  • Circular reference: A has an attribute that references B, and B has an attribute that references A. If both are strong references, neither object can be released.
  • Infinite loop: If there is an infinite loop in a ViewController, the ViewController cannot be released even if the view corresponding to the ViewController disappears.

2. Which keyword is generally used to modify block and why?

Blocks are usually modified with the copy keyword. The use of copy in blocks is a "tradition" inherited from MRC. In MRC, the block of the method content is in the stack area, and copy can be used to put it in the heap area. But in ARC, it doesn't matter whether it is written or not: the compiler automatically copies the block.

3.NSString (or NSArray, NSDictionary) declared with @property often uses the copy keyword. Why? What problems may arise if the strong keyword is used instead?

Answer: The copy keyword is often used when declaring NSString, NSArray, and NSDictionary with @property because they have corresponding variable types: NSMutableString, NSMutableArray, and NSMutableDictionary. Assignment operations may be performed between them. To ensure that the string value in the object does not change accidentally, a copy should be made when setting the new property value.

If we use strong, then this property may point to a mutable object. If this mutable object is modified externally, it will affect the property.

The ownership expressed by this trait is similar to that of strong. However, the setting method does not retain the new value, but "copies" it. When the attribute type is NSString, this trait is often used to protect its encapsulation, because the new value passed to the setting method may point to an instance of the NSMutableString class. This class is a subclass of NSString and represents a string whose value can be modified. If the string is not copied at this time, then after the attribute is set, the value of the string may be changed without the object's knowledge. Therefore, a copy of the "immutable" string is required to ensure that the string value in the object will not be changed accidentally. As long as the object used to implement the attribute is "mutable", a copy should be made when setting the new attribute value.

4.The relationship between runloop, autorelease pool and threads.

Each thread (including the main thread) has a Runloop. For each Runloop, the system will implicitly create an Autorelease pool, so that all release pools will form a stack structure like callstack. At the end of each Runloop, the Autorelease pool at the top of the stack will be destroyed, so that every Object in this pool will be released.

5. What is the essence of @property? How are ivar, getter, and setter generated and added to this class?

There are two major concepts of "property": ivar (instance variable) and access method (access method=getter), that is, @property = ivar + getter + setter.

For example, the following class:

  1. @interface WBTextView :UITextView
  2. @property (nonatomic,copy)NSString *placehold;
  3. @property (nonatomic,copy)UIColor *placeholdColor;
  4. @end  

After the class completes the definition of attributes, the compiler will automatically write methods to access these attributes (autosynthesis). The class written by the above code is equivalent to the following code:

  1. @interface WBTextView :UITextView
  2. - (NSString *)placehold;
  3. -( void )setPlacehold:(NSString *)placehold;
  4. -(UIColor *)placeholdColor;
  5. -( void )setPlaceholdColor:(UIColor *)placeholdColor;
  6. @end  

For detailed introduction, please see: http://blog.csdn.net/jasonjwl/article/details/49427377

6. Write a setter method to complete @property (nonatomic, retain) NSString *name and @property (nonatomic, copy) NSString *name respectively.

The retain property setter method retains the new value and releases the old value, then updates the instance variable to point to the new value. The order is important. If the old value is released before the new value is retained, and the two values ​​point to the same object, the release operation executed first may cause the system to recycle the object.

  1. -( void )setName:(NSString *)name
  2. {
  3. [name retain];
  4. [_name release];
  5. _name = name;
  6. }
  7. -( void )setName:(NSString *)name
  8. {
  9.       
  10. [_name release];
  11. _name = [name copy];
  12. }

7. Talk about the difference between assign vs weak, _block vs _weak

Assign is applicable to basic data types, weak is applicable to NSObject objects and is a weak reference.

In fact, assign can be used to modify objects, so why not use it? Because after the object modified by assign is released, the pointer address still exists, that is, the pointer is not set to nil. If this address is allocated in subsequent memory allocation, the program will crash. After the object modified by weak is released, the pointer address will be set to nil.

_block is used to modify a variable, and this variable can be modified in the block.

_block: Variables modified with _block will be retained in the block code block (under ARC, not under MRC)

_weak: Variables modified with _weak will not be retained in the block code block

8. Please tell me if there is any problem with the following code. If so, please modify it.

  1. @autoreleasepool {
  2. for ( int i = 0 ; i[largeNumber; i++) { (Due to recognition issues, the angle brackets in this line of code are replaced by square brackets)
  3. Person *per = [[Person alloc] init];
  4. [per autorelease];
  5. }
  6. }

Principles of memory management: If you use alloc, copy, and retain on an object, you must use the corresponding release or autorelease. At first glance, this question has alloc and autorelease, and there should be no problem matching the two. But although autorelease will reduce the reference count by one, it does not reduce it by one immediately. Its essential function is just to put the object into the autorelease pool closest to it. When the autorelease pool is destroyed, a release message will be sent to each object in the autorelease pool. The problem with this question lies in autorelease. Because largeNumber is a very large number, and autorelease cannot reduce the reference count by one immediately, it will cause a memory overflow problem before the loop ends.

The solution is as follows:

  1. @autoreleasepool {
  2. for ( int i = 0 ; i[ 100000 ; i++) { (Due to recognition issues, the angle brackets in this line of code are replaced by square brackets)
  3. @autoreleasepool {
  4. Person *per = [[Person alloc] init];
  5. [per autorelease];
  6. }
  7. }
  8. }

Add an automatic release pool inside the loop to ensure that each object created can be released in time.

9. Is there any problem with the following code? If so, please modify it?

  1. @autoreleasepool {
  2. NSString *str = [[NSString alloc] init];
  3. [str retain];
  4. [str retain];
  5. str = @ "jxl" ;
  6. [str release];
  7. [str release];
  8. [str release];
  9. }

This question has the same memory leak problem as question 8: 1. Memory leak 2. Objects pointing to the constant area cannot be released.

The pointer variable str originally pointed to a heap area, but after reassigning str, the pointer of str changed from pointing to the heap area to pointing to the constant area. The variables in the constant area do not need to be released at all, which results in the original heap area not being released, causing a memory leak.

10. When is the weak keyword used? How is it different from assign? When is the weak keyword used?

  • In ARC, when circular references are likely to occur, they are often resolved by making one end weak.
  • It has already been strongly referenced once, so there is no need to strongly reference it again. Weak is also used at this time. Custom control properties generally also use weak.

Differences:

  • Weak This trait indicates that the property defines a "non-owning relationship". When setting a new value for this property, the setting method neither retains the new value nor releases the old value. This feature is the same as assign, but when the object referred to by the property is destroyed, the property value will also be cleared. The "setting method" of assign only performs simple assignment operations on "scalar types" (such as CGFloat or NSInteger, etc.).
  • Assign can be used with non-OC objects, while weak must be used with OC objects.

11. Memory management semantics (differences between assign, strong, weak, etc.)

  • The assign "set method" only performs simple assignment operations on "scalars".
  • strong This trait indicates that the property defines an "ownership relationship". When setting a new value for this property, the setting method will first retain the new value, release the old value, and then set the new value.
  • weak This trait indicates that the property defines a "non-owning relationship". When setting a new value for this property, the setter neither retains the new value nor releases the old value. This trait is similar to assign, but the property value is cleared when the object the property refers to is destroyed.
  • unsafe_unretained The semantics of this trait are the same as assign, but it is applicable to "object types". This trait expresses a "non-ownership relationship". When the target object is destroyed, the attribute value will not be automatically cleared, which is different from weak.
  • copy The ownership expressed by this trait is similar to strong. However, the setting method does not retain the new value, but "copies" it. When the attribute type is NSString*, this trait is often used to protect its encapsulation, because the new value passed to the setting method may point to an instance of the NSMutableString class. This class is a subclass of NSString and represents a string whose value can be modified. If the string is not copied at this time, then after the attribute is set, the value of the string may be changed without the object's knowledge. Therefore, a copy of the "immutable" string is required to ensure that the string value in the object will not change accidentally. As long as the object used to implement the attribute is "mutable", a copy should be made when setting the new attribute value.

We will continue to add content about memory management and multithreading in the future, and will continue to update..., so stay tuned!

  • refer to:
  • Hiring a reliable iOS
  • Reference answers to interview questions about "Recruiting a reliable iOS developer" (Part 1)
  • Matt Galloway "Effective Objective-C 2.0"

<<:  How to make users feel that your app loads quickly

>>:  The future of interaction! 5 ways to help you design easy-to-use touch gestures

Recommend

In 5 years, 20 years...which workers will be threatened by big AI models?

What impact will large language models (LLMs) lik...

Windows 10 Mobile version 10166 released: a lot of BUG fixes

Microsoft officially released the Windows 10 Mobi...

Who knows, family members? ChatGPT actually knows "flattery"!

Have you ever thought that the answers generated ...

What was it like to be a teacher in ancient times?

1 Today (September 10) is the 37th Teachers' ...

CCTV's "Weekly Quality Report": Hidden Concerns of Mobile Payment

Introduction: CCTV's "Weekly Quality Repo...