Based on article

1. How many bits are in a byte? How many characters are in a Chinese character? How many bits of a letter A Chinese character is equal to two English letters is equal to two bytes, and a byte is eight bits

  1. Write a standard macro MIN that takes two arguments and returns the smaller one define MIN (A,B) ( (A) <= (B) ? (A) : (B) )
  2. The difference between a constant defined by define and a const
A constant defined by const is stored in a constant table at runtime, automatically allocated memory, and type-checked at compile timeCopy the code
  1. static
1). On variables: When a local variable is declared static, the storage mode (lifetime) of the variable is changed to make it a static local variable. That is, memory is allocated for the variable at compile time and the storage unit is not released until the program exits. This makes the local variable memorizable, remembering the last data, but because it is still a local variable, it can only be used inside the code block (scope invariant). ------- External variables are variables defined outside all code blocks {}. They default to static variables. Memory is allocated at compile time and released at program end. It also has a wide scope, is valid throughout the file and can even be referenced by other files. To limit the scope of some external variables so that they are valid only in this file and cannot be referenced by other files, declare them static. On functions: When you use static for a function definition, it affects how the function is wired so that the function is only valid inside this file and not visible to other files. Such functions are also called static functions. The advantage of using static functions is that you don't have to worry about interfering with functions with the same name in other files, and it's also a protection mechanism for the function itself. If you want other files to refer to local functions, use the extern keyword in the function definition to indicate that the function is external and can be called by other files. Extern is also used to declare external functions in files that reference external functions defined in other files.Copy the code
  1. How does a network request with asynchronous function return a value
+ (NSString *)httpNet {dispatch_semaphore_t signal = dispatch_semaphore_create(1); __block NSString *objectID; [UIView animateWithDuration:3 animations:^{objectID = @"222"; dispatch_semaphore_signal(signal);}]; dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER); return objectID; Return + (NSString *)httpNetBlock (void(^)(UIImage *Image))blockCopy the code
  1. • The GCD method allows methods in a block to be executed in the main thread by sending a block to the main thread queue
Dispatch_async (dispatch_get_main_queue(), ^{// method to execute});Copy the code

• NSOperation method

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{// method to execute}]; [mainQueue addOperation:operation];Copy the code

• NSThread method

[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];

[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];

[[NSThread mainThread] performSelector:@selector(method) withObject:nil];
Copy the code

• RunLoop method

[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];

Copy the code
  1. NSTimer created, in which thread running with scheduledTimerWithTimeInterval created, in which thread creation will be added to the RunLoop which thread is running on which thread, create the Timer, The RunLoop added to the thread will run on that thread
  2. NSNotification is received in which thread, is it received asynchronously or synchronously • The thread that received the notification is the same thread that sent the notification • NSNotification is synchronous, The NSNotificationCenter will wait until all the recipients have received and processed the notification before returning the poster
  3. The difference between ID and NSObject star
typedef struct objc_object *id

Copy the code

• ID can be understood as a pointer to an object. All oc object ids can be pointed to, the compiler does no type checking, and the id calls any existing methods without an error at compile time. Of course, if the object pointed to by this ID does not have the method, the crash will still crash. • NSObject * must point to a subclass of NSObject, and only call a method in NSObjec or else do a cast. • Not all OC objects are subclasses of NSObject, and some inherit from NSProxy. The types that NSObject * can point to are subsets of IDS.

  1. NSProxy & NSObject NSObjetct: • NSObject applies to all objects under Object-C. If objects comply with this protocol, waves are considered first-class objects (-class). In addition, the retain, release, autorelease methods of objects that comply with this protocol are also subject to the objects management and release methods defined in Foundation. Objects can also be managed by objects in containers, such as objects defined by NSArray and NSDictionary. Cocoa’s root classes also follow this protocol, so all objects that inherit from NSObjects have features that follow this protocol.

• NSProXY: NSProXY is a virtual base class that defines an API for objects that behave like proxies for other objects or that do not exist. – Generally, messages sent to the broker are forwarded to a real object or the broker loads (or transforms itself into) a real object. • NSProxy base classes can be used to transparently forward messages or lazy initialization of expensive objects

  1. • InstanceType is a keyword provided by Clang since 3.5 that represents an Objective-C object of unknown type returned by a method. According to the Cocoa naming rules, methods that satisfy the following rules: Class methods that start with alloc or new. Instance methods that start with autorelease, init, retain, or self return an object of the class type of the method. These methods are called associated return types
NSArray *array = [[NSArray alloc] init];  
Copy the code

Instancetype is used to make methods that are not associated with a return type return the type of the class. • The ability to determine object types helps the compiler better locate code writing problems for us, such as:

[[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; //  "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"  
  
[[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error)  

Copy the code

In case the first line of code, as a result of the [[NSArray alloc] init] as a result of NSArray *, so the compiler can detect whether NSArray implementation depending on the type of the returned data mediaPlaybackAllowsAirPlay method. It helps developers find errors at compile time. The second line of code, due to the array does not belong to correlation method return type, [NSArray array] returns the id type, the compiler does not know whether the object id type implements mediaPlaybackAllowsAirPlay method, (1) InstanceType can return objects of the same type as the class in which the method is located. Id can only return objects of unknown type. (2) InstanceType can only be used as a return value, not as a parameter like id

  1. KVO, NSNotification, Delegate, and Block

•KVO is the Observer pattern implemented by cocoa framework. It is usually used in conjunction with KVC to monitor changes in a value, such as the height of a View. It’s a one-to-many relationship, where a change in a value notifies all observers.

•NSNotification is a notification and also a one-to-many usage scenario. In some cases, KVO and NSNotification are the same, both notifying each other of state changes. The feature of NSNotification is that the observer needs to send the notification actively first, and then the observer registers the monitoring to respond, which is one step more than KVO to send the notification. However, its advantage is that the monitoring is not limited to the change of attributes, but can also monitor a variety of state changes, with a wide monitoring range and more flexible use.

• A delegate is something I don’t want to do and delegate it to someone else. For example, when a dog needs to eat, it notifies its owner through a delegate, and the owner cooks, serves, and pours water for him. The dog doesn’t need to care about these operations. All it needs to do is call its delegate, and other classes do the required operations. So the delegate is one-to-one.

• Block is another form of delegate, a form of functional programming. Using scenarios like a delegate is more flexible than a delegate, and the implementation of the proxy is more intuitive.

• The common usage scenario of KVO is data, and the requirement is data change, such as stock price change, we usually use KVO (Observer mode). A typical delegate usage scenario is an action, and a requirement is someone else doing something for me, like buying or selling a stock, and we use a delegate. Notification is generally used to make global notifications, such as telling people to buy good news. A delegate is a strong association, where the delegate and the agent know each other, so if you entrust someone else to buy the stock you need to know the broker, and the broker doesn’t need to know their customers. Notification is weak correlation. When good news is sent, you can respond to it without knowing who sent it, and the person who receives the message with you also can send the message without knowing who received the message

  1. Synthesize & denamic • The @sythesize directive tells the compiler to generate getter/setter methods at compile time. • Implement the method yourself via the @dynamic directive. Some access is created dynamically at run time, such as the NS-Managed Object class in CoreData

  2. The difference between imageName and mageWithContextOfFile? • When loading with imageNamed, images are cached in memory after use, which consumes more memory and is fast to load. Even if the generated object is released by autoReleasePool, the cache is not released. If the image is large or has many images, this method consumes a lot of memory and may cause an overflow of memory. ImageNamed uses a caching mechanism, if the cache has loaded images, directly read from the cache, no longer need to read the file, more efficient. • ImageWithContextOfile loading, images are not cached, slow loading. • Heavy use of imageNamed can add CPU time where caching is not needed. When the application needs to load a large image and use it once, there is no need to cache the image. Using imageWithContentsOfile is the most economical way. This will not cause the CPU to waste too much time on unnecessary caches because of the large number of Ullmage elements

  3. • Memory overflow encountered in the project development • When sliding a list, the memory grew unexplained. The reasons are as follows: • No REUSE of the UITableView; Realloc each displayed cell with an autorelease; As a result, the cell memory continues to increase. • Each cell displays a separate UIView, and a memory leak occurs in UIView, causing the cell’s memory to grow; • Memory grows inexplicably when images are accessed frequently; Frequent access to network images leads to iOS internal API, which continuously allocates buffer in the form of Autorelease to deal with image decoding and display; Using picture cache can alleviate this problem; • Open and close SQLite frequently, causing memory to grow • Release is forgotten in non-ARC mode • Less use of [UIImage imageNamed] • AutoReleasePool is forgotten in background threads

  4. Memory leaks encountered in project development • Improper use of third-party frameworks • block cyclic references (correctly using copy) • Delegate cyclic references (correctly using weak) • NSTimer cyclic references (secondary encapsulation of NSTimer, Or repeats NO is the correct release) • memory processing for non-OC objects (CF class CG class) • map class processing (agents and pins etc.) • large number of loop memory inflations (for loop is released at the end of the loop, so put the code logic that needs to loop in)

17.NSCache & NSDcitionary NSCache differs from mutable collections in several ways: • The NSCache class combines various automatic deletion strategies to ensure that it does not take up too much system memory. If other applications require memory, the system automatically implements these policies. When these policies are invoked, objects are removed from the cache to minimize memory footprint. •NSCache is thread-safe, and we can add, remove, and query objects in the cache in different threads without locking the cache area. • Unlike NSMutableDictionary objects, a cache object does not copy key objects. •NSCache is similar to NSDictionary, except that when the system reclaims memory, it automatically deletes its contents. (1) can store (using memory, of course) (2) keep strong applications, regardless of garbage collection. => this – point with NSMutableDictionary(3) has fixed customers.

•UlView is the basis of interface elements in iOS, from which all interface elements are inherited. It itself is implemented entirely by CoreAnimation (this doesn’t seem to be the case on Mac). The real drawing part of it is managed by a class called CAL Ayer (Core Animation Layer). UIView itself, more like a CAL Ayer manager, accesses its properties related to drawing and coordinates, such as frame, bounds, etc., essentially internally accessing the properties related to the CAL Ayer it contains. •UIView has an important property layer that returns its primary CAL Ayer instance. •UIView’s CAL ayer is similar to UIView’s tree of child views, and you can also add child layers to its layer for special representations. The CALayer layer can be nested. • The AYER tree of UIView is maintained in three copies within the system. These are logical trees, which code can manipulate; The animation tree is an intermediate layer on which the system changes properties and performs various rendering operations. Display tree, whose contents are currently being displayed on the screen.

  1. Do Property in iOS Category and Protocol automatically generate setter/getter methods
  2. The object is released early. Wild Pointers, null Pointers, zombie objects
  3. Runtime memory model (ISA, objects, classes, Metaclass, structure storage information, etc
struct objc_class : objc_object { // Class ISA; Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags class_rw_t *data() { return bits.data(); }}Copy the code

The first element of the class object isa hidden element (from the parent). This attribute is isa, which points to the metaclass. The second element is Classsuperclass, which points to its parent; The third element is cache_t cache, the associated cache of a class; The fourth element is class_datA_bits_t bits, which returns information about the class store. Class superclass is also a pointer, occupying 8 bytes; Class isa isa pointer that takes 8 bytes; Cache_t is a structure where the first element is a pointer of 8 bytes and the second and third elements are int32 of 4 bytes each, for a total of 16 bytes. Attributes, methods, and protocols that follow in a class are stored in class_rw_t class_ro_t, It stores properties, methods, and protocols that the current class has identified at compile time.

  1. The design of metalClass can see from the structure of objC_Object that the final NSObject metaclass isa points to itself, forming a closed loop. Meta Class: a Class that is a Class object, i.e. : Metaclass represents the object of a Class object. It stores the Class methods of a Class. Its purpose is to separate the instance from the list of related methods and construction information of the Class, so that each can perform its own duties and conform to the design principle of a single responsibility. For a full explanation, please go here
  2. Class_copyIvarList and class_copyPropertyList and objC_method_list Class_copyIvarList: Gets the variables class_copyPropertyList modifies and defined inside the @implementation in the M file Class_copyPropertyList: gets variables decorated with @property, and objc_method_list: stores a list of methods for the class, which you can get with class_copyMethodList
  3. Message forwarding mechanism, message forwarding mechanism and the advantages and disadvantages of other languages message mechanism comparison
(BOOL)resolveInstanceMethod:(SEL)selector + (BOOL)resolveClassMethod:(SEL)selector The processing of a third party - (id) forwardingTargetForSelector: (SEL) selector / / the third stage: Standard message forwarding process - (NSMethodSignature *) methodSignatureForSelector: (SEL) aSelector - forwardInvocation: (NSInvocation (void) *) invocation / / stage 4: error - (void) doesNotRecognizeSelector aSelector: (SEL) {}Copy the code

See the full process analysis here

  1. Method = SEL + IMP. IMP: is the implementation of the Method, only the function implementation of the structure pointer. SEL: is the name of the Method. Method: is the type pointer to objc_method, which is a structure.
  2. Weak, SideTable, weak Key is the address of the referenced object, and value is an array of Pointers to weak. Weak is a weak reference. Weak does not count +1 for the reference object. 1. During initialization, the Runtime calls the objc_initWeak function and initializes a new weak pointer to the address of the object. 2, add reference: objc_initWeak function, call objc_storeWeak() function, objc_storeWeak() function is to update the pointer pointing, create the corresponding weak reference table. 3. When releasing, call the clearDeallocating function. The clearDeallocating function first fetches an array of weak pointer addresses based on the object’s address, then iterates through the array to set it to nil, deletes the entry from the Weak table, and clears the object’s record.
Struct SideTable {// Spinlock_t slock; // Hash table RefcountMap refcnts; Weak_table_t weak_table; // Weak references the global hash table weak_table_t weak_table; }Copy the code
  1. Methods: 1 dispatch_group_t + dispatch_group_notify
- (void)runDispatchTest:(NSArray *)images{ NSMutableArray* result = [NSMutableArray array]; for (UIImage* image in images) { [result addObject:[NSNull null]]; } dispatch_group_t group = dispatch_group_create(); for (NSInteger i = 0; i < images.count; i++){ dispatch_group_enter(group); Dispatch_group_async (group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT) 0), ^{// NSLog(@" Queue group: there is a time-consuming operation completed!" ); [uploadImgae startWithCompletionBlockWithSuccess: ^ (__kindof YTKBaseRequest * _Nonnull request) {NSLog (@ "first % d pictures uploaded successfully: %@", (int)i + 1, request.responseObject); @synchronized (result) {// NSMutableArray result[I] = request.responseObject;  } dispatch_group_leave(group); } failure:^(__kindof YTKBaseRequest * _Nonnull request) {NSLog(@" %d image failed to upload: %@", (int)i + 1, request.error); }]; }); } /** * if all tasks are completed, */ dispatch_group_notify(group, dispatch_get_main_queue(), ^{// NSLog(@" All the previous time-consuming operations are complete, go back to the main thread for related operations "); For (id response in result) {NSLog(@" upload completed data %@", response); }}); }Copy the code

2 dispatch_group_t + dispatch_group_notify

Submit a fence function to execute, and it waits for the fence function to finish executing before executing the next line of code. The synchronous fence function dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t blCOk) is executed on the main thread. Dispatch_barrier_async (dispatch_queue_t queue, dispatch_block_t blCOk) dispatch_queue_t queue (dispatch_block_t blCOk); Dispatch_barrier_sync waits for its own barrier to end before adding and executing tasks following the barrier (4, 5, 6). Dispatch_barrier_async inserts its barrier tasks into the queue. It does not wait for its barrier tasks to end. It continues to insert subsequent tasks (4, 5, 6) into the queue and then executes the task.Copy the code

3 NSOperationQueueu adds a dependency or waits

- (void)operationQueueMethod { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; queue.maxConcurrentOperationCount = 2; NSBlockOperation *op_one = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" downloading first picture ");}]; NSBlockOperation *op_two = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" downloading the second image ");}]; [queue addOperation:op1]; [queue addOperation:op2]; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ UIGraphicsBeginImageContext(CGSizeMake(300, 400)); [self.imageOne drawInRect:CGRectMake(0, 0, 150, 400)]; [self.imageTwo drawInRect:CGRectMake(150, 0, 150, 400)];  UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();  dispatch_async(dispatch_get_main_queue(), ^{ }); }]; [operation addDependency: op1]; [operation addDependency: op2]; [queue addOperation:operation]; */ [queue addOperations:@[op_one, op_two] waitUntilFinished:true]; / / will block the main thread [queue addOperationWithBlock: ^ {UIGraphicsBeginImageContext (CGSizeMake (300, 300));  [self.imageOne drawInRect:CGRectMake(0, 100, 150, 300)]; [self.imageTwo drawInRect:CGRectMake(180, 100, 150, 300)];  UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();  dispatch_async(dispatch_get_main_queue(), ^{ UIImageView *imageView = [[UIImageView alloc] initWithImage:newImage]; [self.view addSubview:imageView]; self.textLabel.text = @" ";});}]; NSLog(@" the main thread will wait until the queue finishes, so it blocks the main thread "); }Copy the code

# in the article

  1. Find the nearest common ancestor of two UIViews. Find the nearest common ancestor of two nodes in a normal binary tree. Suppose two views are UIViewA and UIViewC, where UIViewA inherits from UIViewB, UIViewB inherits from UIViewD, UIViewC inherits from UIViewD; So A->B->D, C->D let’s put all the points in A path into NSSet first. Since the internal implementation of NSSet is a hash table, the time complexity of querying elements becomes O(1). We have N nodes in total, so the total time complexity is optimized to O(N).
- (void)viewDidLoad { [super viewDidLoad]; Class commonClass1 = [self commonClass1:[ViewA class] andClass:[ViewC class]]; NSLog(@"%@",commonClass1); / / output: 2018-03-22 17:36:01.868966+0800 The nearest public parent of two UIViews [84288:2458900] ViewD} // Get all superClasses:(NSArray *)superClasses:(Class) Class { if (class == nil) { return @[]; } NSMutableArray *result = [NSMutableArray array]; while (class ! = nil) { [result addObject:class]; class = [class superclass]; } return [result copy]; } - (Class)commonClass1:(Class)classA andClass:(Class)classB { NSArray *arr1 = [self superClasses:classA]; NSArray *arr2 = [self superClasses:classB]; NSSet *set = [NSSet setWithArray:arr2]; for (NSUInteger i =0; i<arr1.count; ++i) { Class targetClass = arr1[i]; if ([set containsObject:targetClass]) { return targetClass; } } return nil; }Copy the code

If there is any mistake in my understanding, please be sure to point out. Thank you very much!