The answers to the interview questions are all about the basics of iOSCopy the code

1. How much memory does an NSObject take up?

  • The system allocates 16 bytes to the NSObject object (obtained by the malloc_size function)
  • But NSObject uses only 8 bytes of space internally (available in 64-bit environments via class_getInstanceSize)

Where is the isa pointer to the object?

  • The ISA of an instance object points to a class object
  • The ISA of a class object points to a meta-class object
  • The ISA of a meta-class object points to a meta-class object of the base class

3. Where is the OC class information stored?

  • Object methods, properties, member variables, and protocol information are stored in class objects
  • Class method, stored in a meta-class object
  • The specific value of the member variable is stored in the Instance object

4. How does iOS implement KVO for an object? (What is the nature of KVO?)

  • Use the RuntimeAPI to dynamically generate a subclass and have the Instance object’s ISA point to the new subclass
  • When modifying the properties of an instance object, Foundation’s _NSSetXXXValueAndNotify function √ willChangeValueForKey is called: Tick the superclass original didChangeValueForKey setter) : tick internal will trigger the listener (Oberser) surveillance methods (observeValueForKeyPath: ofObject: change: context:)

5. How to trigger KVO manually?

  • Manually call willChangeValueForKey and didChangeValueForKey:

6. Does directly modifying a member variable or attribute trigger KVO?

  • Modifying a member variable does not trigger KVO
  • Modifying properties triggers KVO

7. What is the assignment and value process of KVC? How does it work?

7.1. KVC assignment

PTLPerson *p = [[PTLPerson alloc] init]; self.person = p; PTLDog *dog = [[PTLDog alloc] init]; // assign dog to man [p]setValue:dog forKeyPath:@"dog"]; // 1.4 Assigning dog weight via KVC will automatically find the dog-owned weight attribute [psetValue: @ 10.0forKeyPath:@"dog.weight"];
NSLog(@"books = %@", [p valueForKeyPath:@"dog.weight"]);
[dog print];
Copy the code

7.2. KVC value

NSMutableArray *tempM = [NSMutableArray array]; // 2.1kvc fetches the value of price from booksfor (PTLBook *book in [p valueForKeyPath:@"books"]) {
    [tempM addObject:[book valueForKeyPath:@"price"]];
}
NSLog(@"% @", tempM); NSLog(@)"Max = %@", [[p valueForKeyPath:@"books"] valueForKeyPath:@"@max.price"]);
Copy the code

Principle of 7.3,

  • KVO is an objective-C implementation of the observer design pattern. The other is notification. KVO provides A mechanism to specify an observed object (such as class A). When A property of the object (such as the string name in A) changes, the object will be notified and react accordingly to the project under the MVC design architecture. KVO mechanism is suitable for the communication between the Mode model and the controller. For example: in the code, create attribute data in model class A, create observer in the controller, once the change of attribute data will receive the notification of the observer, and then use the callback method in the controller through KVO to realize the update of view B; (The application in this article is one such example.)

  • Automatic key-value observing is implemented using a technique called ISa-Swizzling… When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, Pointing to an intermediate class rather than at the true class… The implementation of KVO relies on the powerful Objective-C Runtime [from Apple above] It can be seen from the documentation of Apple’s implementation of KVO mechanism, and there is not too much detail description, but we can explore the underlying implementation principle of KVO mechanism through the methods provided by The Runtime.

  • When viewing object A, the KVO mechanism dynamically creates A subclass of object A’s current class and overrides the setter method for the observed property keyPath for the new subclass. Setter methods are then responsible for notifying the observed object of changes to its properties.

  • Apple uses ISa-Swizzling to implement KVO. When observing object A, the KVO mechanism dynamically creates A new object named: NSKVONotifying_A is A new class that inherits from object A, and KVO is NSKVONotifying_A that overrides the setter method to observe the property, and the setter method is responsible for calling the original setter method before and after, Notifies all observed objects of changes in property values.

  • NSKVONotifying_A class analysis: in this process, the isa pointer of the observed object is changed from pointing to the original class A by the KVO mechanism to pointing to the newly created subclass NSKVONotifying_A to realize the monitoring of the change of the current class attribute value. So when we look at the application level, we are completely unaware that there is a new class, this is the system “hiding” the underlying implementation of KVO, making us think it is the original class. However, if we create a new class named “NSKVONotifying_A” (), we will find that the program will crash when the system runs to the section of the register KVO code, because the system dynamically creates the middle class named NSKVONotifying_A when the register listener, and points to this middle class. Calls to setters on that object therefore invoke the override setter, thereby activating the key-value notification mechanism.

  • Subclass setter method profile :KVO’s key-value observation notifications depend on NSObject’s methods willChangeValueForKey and didChangevlueForKey, which call two methods before and after accessing a value: Before the observed property changes,willChangeValueForKey: is called to inform the system that the value of the keyPath property is about to change; When the change occurs, didChangeValueForKey: is called to inform the system that the keyPath property value has changed; After observeValueForKey: ofObject: change: context: will be invoked. And override setter methods for observing properties. This inheritance injection is implemented at run time, not compile time. KVO calls access methods for the observer property override of subclasses.

-(void)setName:(NSString *)newName 
{ 
[self willChangeValueForKey:@"name"]; KVO always calls [super] before calling the accessor methodsetValue:newName forKey:@"name"]; // Call the accessor method of the parent class [self didChangeValueForKey:@]"name"]; //KVO always calls} after calling the accessor methodCopy the code

8. How does Category work?

  • After Category compilation, the underlying structure is struct category_t, which stores classified object methods, class methods, attributes, and protocol information
  • At runtime, the Runtime merges the Category data into the class information (class object, metaclass object).

9. What is the difference between Category and Class Extension?

  • When Class Extension is compiled, its data is already included in the Class information
  • Category data is merged into the class information at runtime

Is there a load method in Category? When is the load method called? Can the load method inherit?

  • With the load method
  • The load method is called when the Runtime loads a class or class
  • The load method can be inherited, but usually the system does not automatically call the load method

What is the difference between the +load and +initialize methods? What order are they called in the category? And how they call each other when inheritance occurs?

+load
  • The +load method is called when the Runtime loads classes and classes
  • The +load of each class and category is called only once during the running of the program
  • Call order:
  • The +load of the subclass will be called first before the +load of the parent class is called
  • +load √ Call in compile order (compile first, call first)
+initialize
  • The + Initialize method is called the first time the class receives a message
  • Initialize (+initialize); initialize (+initialize);
  • The big difference between +initialize and +load is that +initialize is called via objc_msgSend, so it has the following features: The +initialize of the parent class is called (so the +initialize of the parent class may be called multiple times) √ If the class implements +initialize, the +initialize call of the class itself is overridden

Can I add member variables to a Category? If so, how do YOU add member variables to a Category?

  • By default, member variables cannot be added to a category because of the underlying structure of the category. But it can be done indirectly by associating objects

13. How does Block work? What is the essence?

  • A block is also essentially an OC object with an ISA pointer inside it
  • An OC object that encapsulates the function call and the calling environment

14. What does __block do?

  • The __block specifier, like static, auto, and register, puts the memory address of the “external variable” in the stack into the heap whenever it is observed that the variable is held by the block. In turn, you can modify the values of external variables inside the block.
  • __block can be used to solve the problem of not being able to modify the value of the auto variable inside a block
  • __block cannot modify global or static variables.
  • The compiler wraps a __block variable into an object

15. Why copy is the attribute modifier for block? What are the implications of using blocks?

  • Once a block is not copied, it is not on the heap
  • Usage Note: Circular reference problem

16, block modify NSMutableArray, do I need to add __block?

  • Don’t need
  • When a variable is a pointer, the block just makes a copy of that pointer, both Pointers to the same address. Therefore, changes made to the pointer inside the block also apply outside the block.

17. What about isa Pointers?

  • Instance isa refers to class. When an object method is called, the class is found through the instance ISA and the implementation of the object method is found
  • Class isa refers to meta-class. When a class method is called, the class isa finds the meta-class, and finally finds the implementation of the class method to call
  • When a Student instance object calls a Person object method (Student inherits from Person), it finds the Student class through ISA, then finds the Person class through superclass, and finally finds the implementation of the object method to call
  • When a Student class calls a Person class method (Student inherits from Person), Student’s meta-class is found through isa, and then Person’s meta-class is found through superclass. Finally find the implementation of the class method to call
  • Before the ARM64 architecture, ISA was a plain pointer that stored the memory addresses of Class and meta-class objects
  • Starting with the ARM64 architecture, ISA has been optimized to become a common body (Union) structure, and bitfields are used to store more information
  • Starting with 64bit, ISA needs to perform a bit operation to calculate the real address

Isa, superclass summary

  • Instance isa points to class
  • Class’s ISA points to meta-class
  • The ISA of the meta-class points to the meta-class of the base class
  • If there is no superclass, the superclass pointer is nil
  • The superclass of the meta-class refers to the superclass of the superclass of the superclass of the base class
  • Instance calls the trace of the object’s method isa to find the class. If the method does not exist, it finds the superclass
  • Class calls the trace isa of the class method to find the meta-class. If the method does not exist, the superclass will find the superclass