1. How much memory an OC object occupies

The system allocates 16 bytes to NSObject (obtained by the malloc_size function), but only 8 bytes of space are used inside NSObject (obtained by class_getInstanceSize in 64-bit environments).Copy the code

2. Where does the isa pointer to the object point to?

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 classCopy the code

3. Where is the OC class information stored?

Object methods, properties, member variables, and protocol information are stored in the class object in the class method, and in the meta-class object in the specific value of the member variables in the instance objectCopy the code

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 instance object's ISA point to the new subclass. It calls Foundation's _NSSetXXXValueAndNotify function willChangeValueForKey, the original setter for the parent class, didChangeValueForKey, - internal will trigger the listener (Oberser) surveillance methods (observeValueForKeyPath: ofObject: change: context:)Copy the code

5. How do I manually trigger KVO?

// - (void)viewDidLoad {[super viewDidLoad]; Person *person = [[Person alloc]init];; [p addObserver:selfforKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    [p willChangeValueForKey:@"name"];
    [p didChangeValueForKey:@"name"];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    NSLog(@"Observed object :%@, observed attribute :%@, change of value :%@ \n, carrying information :%@", object, keyPath, change, context);
}
Copy the code

6. Does directly modifying a member variable trigger KVO?

KVO will not triggerCopy the code

7. Does modifying attributes via KVC trigger KVO?

Will trigger the KVO KVC within the assignment, will trigger the listener (Oberser) surveillance methods (observeValueForKeyPath: ofObject: change: context:)Copy the code

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

KVC stands for key-value Coding, commonly known as "key-value Coding". It is possible to access a property invocation through a KeysetValue:forKey:
setKey, _setKey - > found on assignment, call accessInstanceVarlableDirctly modified operation value is not found, returns YES call _key, _isKey, Key, isKey to assignmentCopy the code

9. What is the use of Category?

- Add object methods or class methods without modifying the original class code - or associate new attributes for the class - decompose the huge class file usage: - Add instance methods - Add class methods - Add protocol - Add attributes - associate member variablesCopy the code

10. Implementation principle of Category

After Category compilation, the underlying structure is struct category_t, which stores the classified object method, class method, attribute and protocol information. When the program runs, the Runtime will merge the Category data into the class information (class object, metaclass object).Copy the code

11. What is the difference between a Category and a Class Extension?

When Class Extension is compiled, its data is already contained in the Class information, and when Category is run, the data is merged into the Class informationCopy the code

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

- The load method is called when the Runtime loads a class or class. - The load method can be inherited. However, the load method is not automatically called by the systemCopy the code

13. How and when is the initialize method called

The initialize method is called when the class receives a message for the first time. This is done using the Runtime message mechanism objc_msgSend(obj,@selector()). The subclass is called if there is no class, and the parent class is called if the subclass is not implementedCopy the code

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

- Load is called when the class is loaded into memory, priority class -> subclass -> class - initialize is called when the class receives the message for the first time, priority class -> subclass -> parent - depends on the level and compile order - Load is called before mainCopy the code

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

You can't just add a member variable to a Category, However, you can indirectly achieve the effect that a Category has member variables. Category happens at runtime. After compilation, the memory layout of the class has been determined, and member variables cannot be added (the underlying data structure of the Category also has no structure of member variables)Copy the code

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

A block is essentially an OC object that encapsulates a function call and its calling environmentCopy the code

16. What does __block do? What is the use of attention?

If you need to modify the value of an external local variable inside a block, you need to use __block modifier (global variables and static variables can be modified without __block). After __block modifier, the data structure of the local variable will change, and the underlying object will become a structural object, which will be declared inside the structure A member of a __block modifier variable, and the address of the __block modifier variable is stored in heap memory. If you want to change the value of the variable, you can use the isa pointer to find the structure and change the value of the variable. You can change the value of a variable inside a blockCopy the code

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

Once a block is not copied, it is not used on the heap. Note: Circular reference problem (externally using __weak is solved)Copy the code

17. Block to modify NSMutableArray, do I need to add __block?

If you're dealing with an NSMutableArray object, you don't need to, because inside the block you copy the memory address of the NSMutableArray object, you actually operate on the memory address and if you're reassigning an NSMutableArray object, you need to add __blockCopy the code

18. Why can’t a local variable be modified inside a Block

If an external variable is used inside a Block, the same variable will be created inside the Block, and the value of the external variable will be referenced. (just copy the value of the external variable into the inside of the block), the inside of the variable has nothing to do with the outside. On the other hand, the block is essentially a function pointer, An external variable is also a local variable, and it is possible that block uses this variable when the external variable has already been released, causing an error. After adding __block, the memory of the external variable is copied to the heap, which is managed by block.Copy the code

19. Talk about OC’s messaging mechanism

Method calls in OC are actually converted into objc_msgSend function calls, which send a message (selector method name) to the receiver (method caller). At the bottom of objc_msgSend, there are three phases of message sending (current class, parent class lookup), dynamic method parsing, and message forwardingCopy the code
19.1 Message Sending Process
When one of our receivers receives a message, it finds its class object through the ISA pointer, then looks for the corresponding method implementation in the list of class object methods, and if not, finds the class object of its parent through the superClass pointer. If it finds it, it returns it, if it doesn't find it, it goes up and down, eventually it gets to NSObject, and if it doesn't find it, it does dynamic method resolution class method call same as before, except that the ISA pointer finds the metaclass;Copy the code
19.1 Dynamic method resolution mechanism
+ (BOOL)resolveInstanceMethod:(SEL) SEL {resolveInstanceMethod:(SEL) SEL {resolveInstanceMethod:(SEL) SEL {if (sel == @selector(run)) {
        Method method = class_getInstanceMethod(self, @selector(test));
        class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));
        return YES;
    }
    return[super resolveInstanceMethod:sel]; } // class method call +(BOOL) resolveClassMethod:(SEL) SEL....Copy the code

20. Process of message forwarding mechanism

Method of dynamic binding is not found, will be for message forwarding phase / / fast forward - specified message processing object - (id) forwardingTargetForSelector aSelector: (SEL) {if (aSelector == @selector(run)) {
        return [Student new];
    }
    return[super forwardingTargetForSelector:aSelector]; } / / standard message forwarding - signing messages - (NSMethodSignature *) methodSignatureForSelector aSelector: (SEL) {if(aSelector == @selector(run))
    {
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }
    return[super methodSignatureForSelector:aSelector]; } - (void)forwardInvocation:(NSInvocation *)anInvocation{// internal logic to handle}Copy the code

21. What is Runtime? Have you used it in your daily projects?

Objective-c Runtime is a runtime library that supports the dynamic features of Objective-C. All OC code we write is converted to Runtime code at runtime, classes are converted to C constructs, methods are converted to C functions. The message is converted to the corresponding function call in C language. By understanding runtime and source code, you can have a deeper understanding of the characteristics and principles of OC. OC is a highly dynamic programming language, which allows many operations to be postponed until the program is running. The dynamic of OC is supported and implemented by Runtime, which is a set of C language APIS. Encapsulates a lot of dynamic related functions usually written OC code, the bottom is converted into the Runtime API to callCopy the code

22. Runtime application

Use AssociatedObject to add attributes to the class to traverse all the member variables of the class (modify textfield placeholder color, dictionary to model, automatic archiving unfile) exchange method implementation (exchange system method) use message forwarding mechanism to solve the problem that the method can not find the exceptionCopy the code

23. What are the printed results?

[self superClass] and [super superClass] both return a message to the current class. Spuer MJStudent/ MJStudent/ MJerson/MJPerson isKindOfClass Indicates whether the object is the type of the current class or subclass. IsMemberOfClass indicates whether the object is the type of the current class Divided into - object method and + class method 2 - (bool)isMemberOfClass; + (bool)isMemberOfClass; The comparison is to the metaclass second print: 1,0, 0, 0Copy the code

24. Can the following code be executed successfully? If so, what is the print result?

<ViewController: 0x7F9396C16300 >Copy the code

25. Talk about RunLoop. Is it useful in the project?

The main thread is enabled by default to handle various events on the thread. Timers can improve program performance and save CPU resources. When there is something to do, you can do it. Timers, event responses, gesture recognition, interface refreshes, autoreleasePool, and moreCopy the code

26. Implementation logic inside Runloop?

In fact, RunLoop is just such a functiondoThe while loop. When you call CFRunLoopRun(), the thread stays in the loop forever; This function does not return until it times out or is stopped manually.Copy the code

27. How do runloops relate to threads?

Each thread has a unique RunLoop object that is stored in a global Dictionary, thread as key, and RunLoop as value. When the thread is created, it doesn't have a RunLoop object. The RunLoop of the main thread is automatically acquired (created), and the child thread has no RunLoop enabled by defaultCopy the code

28. Relation between Timer and Runloop?

The timer is implemented based on a runloop. The runloop listens to the customizer during the running loop and executes it. Therefore, the timer needs to be added to the runloop. Note that the runloop of the child thread is not enabled by default. If the timer is executed on the child thread, you need to manually enable the runloopCopy the code

29. Add NSTimer that responds every 3 seconds in the program. When dragging the TableView, the timer may not respond.

Mode NSTimer *timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:nil]; [[NSRunLoop currentRunLoop] addTimer:timerforMode:NSRunLoopCommonModes];
Copy the code

30. How does Runloop respond to user actions?

Don't understand what the question is?Copy the code

31. Describe several states of runLoop

Add an Observer to listen for all RunLoop states

32. What is the mode function of runloop?

Runloop can only run in one mode, The default is kCFRunLoopDefaultMode. If the view slides back to UITrackingRunLoopMode, you need to set it manually if you want to run it in multiple modes kCFRunLoopCommonModes; 1. KCFRunLoopDefaultMode: the default Mode of the App, in which the main thread usually runs Interface tracking Mode, to track ScrollView touch sliding, guarantee the interface slip is not affected by other Mode 3. UIInitializationRunLoopMode: When just start the App the first to enter the first Mode, after the completion of the start will no longer use, will switch to the 4 kCFRunLoopDefaultMode GSEventReceiveRunLoopMode: 5. KCFRunLoopCommonModes accept internal modes for system events, usually not used: This is a placeholder Mode, used to mark kCFRunLoopDefaultMode and UITrackingRunLoopMode, not a real ModeCopy the code

33. Do you understand multi-threading?

The CPU can only handle one thread at a time, and only one thread is working on multiple threads executing concurrently. In fact, the CPU schedules (switches) between multiple threads very fast. If the CPU schedules threads fast enough, it creates the illusion of multiple threads executing concurrently. The disadvantages of allocating tasks from different threads to different processors are that new threads consume memory controls and CPU time, and too many threads degrade system line performance.Copy the code

34. What are the multithreading schemes for iOS? Which one do you prefer?

Inclined to GCD, simple and flexible, easy to useCopy the code

35. Have you ever used GCD on a project?

There are two functions that execute tasks dispatch_sync(dispatch_queue_t queue, dispatch_block_t block). Queue: queue block: tasks are performed asynchronously dispatch_async(dispatch_queue_t queue, dispatch_block_t block).Copy the code

36.GCD queue type

GCD queues can be divided into two types of Concurrent Dispatch queues, which allow multiple tasks to execute concurrently (automatically enable multiple threads to execute tasks simultaneously). The concurrency function is only available under the asynchronous (dispatch_async) function Serial Dispatch queues allow tasks to be executed one after another (after one task is completed, the next task is executed)Copy the code

37. Describe the differences between OperationQueue and GCD and the advantages of each

1> GCD is a pure C API, NSOperationQueue is based on the OC version of GCD package 2> GCD supports only FIFO queue columns, 3> NSOperationQueue can easily set dependencies between operations, 4> the NSOperationQueue supports KVO, which monitors whether an operation isExecuted, isFinished, or not. Whether to cancel (isCanceld) 5> The execution speed of GCD is faster than that of NSOperationQueue. Tasks are not too dependent on each other :GCD tasks have dependencies \ or to listen on the execution of tasks :NSOperationQueueCopy the code

38. What are the thread-safe methods?

1. Lock. 2Copy the code

OC What do you know about locks? Ask a second question based on your answer;

Os_unfair_lock ios10 Start OSSpinLock ios10 Discarded dispatch_semaphore Dispatch_mutex dispatch_queue Serial NSLock pair Mutex encapsulation @synchronized performs worstCopy the code

Question 1: Spin versus mutex?

When is it cost-effective to use a spin lock? Threads are expected to wait very short for locks Locking code is called frequently, but contention is rare CPU resources are not tight multi-core processors when is it cost-effective to use mutex? It is expected that the thread will wait for a long time to lock. In the critical area of a single-core processor, IO operations exist. In the critical area, the code is complex or the number of cycles is largeCopy the code

41. Follow-up ii: What should I pay attention to when using the above locks?

Note that deadlocks are easy to cause by using synchronization in serial queuesCopy the code

Question 3: Use C/OC/C++, one or the other, to implement spin or mutex? Dictate!

The principle of locking the two types of locks is as follows: mutex: The thread will change from sleep (locking) -- > RUNNING (unlocking). In the process, there are overhead of context switching, CPU preemption, signal sending and so on. Spin lock: the thread is always running(lock -- > unlock), and the flag bit of the lock is detected in an infinite loop.Copy the code

43. What is the print result of the following code?

Print 1,3 performSelector after is a task implemented based on the timer customizer, and the timer is implemented based on the runloop. 2 in child threads, runloop is disabled by default, so 2 is not executedCopy the code

44. What is the print result of the following code?

Print 1 start, the thread is destroyed. tasktestIt's not gonna work.Copy the code

45. What should I pay attention to when using CADisplayLink and NSTimer?

CADisplayLink ensures that the call frequency and brush frame frequency are always 60FPS, without setting the time interval,60 times per second. CADisplayLink can be used as a proxy to resolve the circular reference. If target makes strong references to them again, circular references are raisedCopy the code

46. Introduce the large areas of memory

Low address -> High address reservation -> Code segment -> Data segment (string constant, initialized global data, uninitialized data)> heap -> stack memory -> Kernel area code segment: compiled code segment: String constants, initialized global variables, or static variables, uninitialized global variables, static variable heap (low > high) dynamically allocated memory stack by alloc malloc calloc (high address from low address) Function call overhead ()Copy the code

47. Explain your understanding of iOS memory management

A newly created OC object's reference count defaults to 1. When the reference count is reduced to 0, the OC object is destroyed, freeing up its memory. A call to retain gives the OC object's reference count +1. So when you call the alloc, new, copy, mutableCopy methods and you return an object, when you don't need that object, you call release or autoRelease and you want to own that object, Let its reference count be +1; Extern void _objc_autoreleasePoolPrint(void) extern void _objc_autoreleasePoolPrint(void);Copy the code

48. What has ARC done for us?

LLVM + Runtime will automatically insert retain and release and autorelease into our code without manual managementCopy the code

49. Implementation principle of weak pointer

The Runtime maintains a weak table that stores all the weak Pointers to an object. The weak table is the weak tablehashAn array of the addresses of the weak pointer and the addresses of the weak pointer. The Runtime lays out the registered classes and puts one in for weak objectshashIn the table. If the reference count of this object is 0, dealloc will be dealloc. If the memory address of the weak object is A, then a will be searched in the weak table, find all the weak objects with a as the key, and set to nil.Copy the code

50. When will the autoRelease object be called Release

IOS registers two observers in the main thread Runloop - the first Observer listens for the kCFRunLoopEntry event, Objc_autoreleasePoolPush () - the second Observer listens for the kCFRunLoopBeforeWaiting event, Objc_autoreleasePoolPop () is called. Objc_autoreleasePoolPush () listens for kCFRunLoopBeforeExit. Objc_autoreleasePoolPop () is called and a release message is sent back to the objects in the poolCopy the code

51. There are local objects in the method. Will they be released immediately after the method

If it is a normal local object, it will be released immediately. If it is placed in autoreleasePool, it will wait for the runloop torelease it before it goes to sleepCopy the code

52. What can happen to the following two pieces of code? What’s the difference?

The first memory will pop, and self.name will keep creating the second memory fixed, using Tagged Pointer to store the value in the addressCopy the code

53. How did you optimize memory in your project?

Memory optimization can be accessed from both memory leaks and memory overhead - reduce memory leaks by using static analysis as well as leaks analysis for instruments note the use of NStimer as well as blocks, delegates, and so on, avoiding circular references - and reduce peak memory usage 1. ImageNamed: The imageNamed method caches images in memory for commonly used images. The imageWithContentsOfFile method frees image memory during view destruction, which is suitable for large images that are not often used. 2. Try to use the reuse mechanism of tableView cell to reduce the extra overhead 3. Try to use thumbnails for tableView list picture display 4. Lazy object loading saves memory overhead. 5. Avoid creating a large number of objects in a short time. Reuse large overhead objects such as NSDateFormatter and NSCalendar 7. Load HTML using wkwebView as much as possible 8. Singletons are not easy 9. Maximum number of concurrent threadsCopy the code

54. What aspects of optimization do you start from?

Lag optimization Startup optimization power consumption optimization APP thin CPU usage, memory usage, network condition monitoring, startup flash back, lag, FPS, crash in use, power consumption monitoring, flow monitoring....Copy the code

55. What are the possible causes of stalling? How do you normally optimize?

1. The most common one is cell reuse. If you do not reuse a cell, a new cell will be created every time a cell is displayed on the screen. If you have a lot of data, you accumulate a lot of cells. If a cell is reused and an ID is created for the cell, the system searches the buffer pool for the recyclable cell whenever a cell needs to be displayed. If cell 2 is not created again, the system searches the buffer pool for the recyclable cell. Avoid rearranging cells. It takes time to arrange and fill cells. For example, if a cell can be placed in a custom class, arrange it when it is initialized. When creating a cell's data source method, the compiler does not create the cell first and then specify the height of the cell. Instead, the compiler determines the height of each cell based on the content and then creates the cell to display. When scrolling, the height is calculated every time the cell enters the virtual. Estimating the height in advance tells the compiler, and when the compiler knows the height, it creates the cell and then calls the height calculation method, wasting time calculating cell 4 that is not displayed. Reduce the number of controls in the cell so that the layout of the cell is roughly the same. Cells with different styles can use different reuse identifiers. Add controls during initialization. Do not use ClearColor, no background color, and do not set opacity to 0. If only a group is updated, use the reloadSection for local updates 7. Load network data, download images, use asynchronous load, and cache 8. Use addView less to dynamically addView 9 to the cell. Load cells on demand. If a cell scrolls quickly, only cell 10 in the range is loaded. Don't implement useless proxy methods, tableView only complies with two protocols 11. High cache row: estimatedHeightForRow cannot exist at the same time as layoutIfNeed in HeightForRow. So my advice is: whenever the line height is fixed, write the estimated line height to reduce the number of line height calls and improve performance. Instead of writing predictive methods for dynamic line height, use a line height cache dictionary to reduce the number of calls to the code 12. Don't do extra drawing work. When you implement drawRect:, its rect parameter is the region to draw, and anything outside that region is not to be drawn. For example, in the above example, CGRectIntersectsRect, CGRectIntersection or CGRectContainsRect can be used to determine whether image and text need to be drawn, and then call the drawing method. 13. Pre-rendered images. There is still a brief pause when a new image appears. The solution is to draw it in a Bitmap context, export it as a UIImage object, and then draw it to the screen; 14. Use the right data structure to store data.Copy the code

56. App startup optimization

1\. Before pre-main * Check useless dynamic libraries (periodically clean up) * Reduce the number of ObjC classes (libraries that are not applicable in the project, discarded code, etc.), methods (selector), categories (category), useless libraries * less to do things in class +load method, Try to put these things until + initiailize1. 2 \. After the main function of didFinishLaunchingWithOptions finish loading before * does not affect the operation of the user experience, do lazy loading, don't all in DidFinishLaunchingWithOptions do * version update, some tripartite initialization, don't need to didFinishLaunchingWithOptions on initialization, finished interface display initialization * some network request delay in. * Some business logic lazy loading * initialization of a third party SDK * configuration of the environment needed to run the APP * initialization of some of your own utility classesCopy the code

57. Optimization of app power consumption

1. Do not refresh the page frequently. If you can refresh one cell line, refresh only one cell line and do not use reloadData.2. Select the correct set NSArray, use index to find fast (insert and delete slowly) dictionaries, use keys to find fast NSSets, which are unordered, use keys to find fast, insert/delete fast 3. Use less arithmetic to get rounded corners. If you must use rounded corners, make the image itself as rounded corners 4. Lazy loading, do not create all subViews at once, but as needed. 5. 6. Image processing image and imageView the same size, avoid redundant operation can use the whole pair of images, increase the application volume, but save THE CPU adjustable size of the image, can save some unnecessary space CALayer,CoreGraphics, and even OpenGL to draw, CPU consumption Cache,cache,cache(all required) the server's cache of corresponding results (picture) the cache of complex computations (UITableView line height) 8. 9. Using ARC to reduce memory errors,dealloc needs to be overwritten and set properties to nil 10. Avoid large XIBs and storyboards, and try to use pure code to develop CPU layer 1. The interval of Timer should not be too short, as long as it meets the requirements 2. 3. Optimize the algorithm and reduce the number of cycles 4. Positioning and Bluetooth are available on demand. After positioning, turn off or reduce the positioning frequency. 5Copy the code

58. App packs slim down

59. Tell me about MVC, MVVM, MVP, and how exactly did you write about it in your project?

Generally, a controller is used to manage data and views. Data and view interaction are implemented through a controller. Views and data are decoupled, but we often bind models to views for everyday use. The model is wrapped inside the view, and the outside doesn't manage the view's internal business logic, which is a variation of data MVC, where the controller just gives the view model data. The disadvantage is that the view and model are coupled; MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel MVVM model-view-viewModel A View interacts with a Model through a Presenter, and a controller manages the Model and view through a PresenterCopy the code

60. What design patterns have you used yourself?

Relate it to your own projectCopy the code

61. How do you think about your architecture when starting a project?

According to modules, MVC function is used to divide.. Combined with their own projects, it is easier to involve a lot of things, relatively complicated, from the whole project architecture to a view architecture; There's no specific answerCopy the code

Reference: iOS Basic Principles class (part 2) /OC object/Associated object/multi-threading/memory management/performance optimization