preface

Recently, I was busy with the stability construction of the company’s project, so I didn’t write much articles! This year, due to the large layoffs in the education industry, the competition is more fierce. Due to the large collection, it will be divided into two parts, and a special topic on algorithms will be launched later. I hope it will be helpful for everyone’s interview, and I also hope that every interview partner can get the desired offer. Don’t memorize answers, it’s better to understand, because the interview will diverge, if you don’t understand, you can’t deal with diverging questions

Modifier of @property

  • Common modifiersassign,weak,strong,retain,copy,nontomic,atomic,readonly,readwrite

Atomic and nonatomic

  • 1.atomicandnonatomicUsed to determineCompiler generationthegetterandWhether the setter is an atomic operation.
  • 2. The atomic:Getter /setter generated by the systemwillEnsure get and set operationstheintegrity.It is not affected by other threads.getterYou can still get oneintactObject (okEnsure data integrity), but thisobjectinmultithreadingUnder the condition ofI don't know for surethe

assign

  • 1. This modifier isDirect assignmentFloating-point, integer, floating-point, etc
  • 2. IfThe weak strong retain copy modifier is not used, thenThe defaultIs the use ofassign
  • 1. 3. Smart mattressObjects can also be assigned, justobjecttheThe counter will not +1Strong, strong, strong
  • 4. If usedModify object properties, then whenObject destroyedafterPointers don't point to nil. SoWild Pointers appearWeak, weak, weak, weak

weak

  • 1.Weak is a weak referenceWeak; weak; weakCounters of reference objects are not incremented by one
  • 2. ReferencesObject is releasedTime automaticIs set to nil, which greatlyavoidtheWild Pointers access bad memoryThe condition that causes a collapse
  • 3. What’s more, I’m weakResolving circular references

Weak principle generalization

  • Weak table weak table weak tableHash table.KeyIs referred toObject address.ValueisThe address array of the weak pointer
  • 2.Runtime maintains oneWeak table, used to store objects that point to an objectAll weak Pointers.Weak tableIt’s actually aThe hash table.KeyIs referred toobjecttheaddress.valueisWeak pointertheaddressThe address value is the address of the pointer to the object.

Value is an array because an object can be pointed to by more than one weakly referenced pointer

Weak principle implementation

1. Initialization

The Runtime calls the objc_initWeak function, which initializes a new weak pointer to the address of the object:

NSObject *obj = [[NSObject alloc] init];
id __weak obj1 = obj;
Copy the code

When we initialize a weak variable, the Runtime calls the objc_initWeak function in nsobject. mm, which is declared in Clang as follows:

id objc_initWeak(id *object, id value);
Copy the code

The objc_initWeak() method is implemented as follows:

Id objc_initWeak(id *location, id newObj) {// Check whether the object instance is valid. newObj) { *location = nil; return nil; Return storeWeakfalse/*old*/, true/*new*/, true/*crash*/> (location, (objc_object*)newObj); }Copy the code

This function is simply an entry point to a deeper function. In general, entry functions make some simple judgments (such as the cache judgment in objc_msgSend) to determine whether the class object to which the pointer points is valid. Otherwise, object is registered as an __weak object pointing to value. The objc_storeWeak function should do this.

Note: The objc_initWeak function has one prerequisite: object must be a valid pointer that is not registered as an __weak object. Value can either be null or point to a valid object.

2. Add a reference

The objc_initWeak function calls the objc_storeWeak() function, which updates the pointer pointer and creates the corresponding weak reference table. The objc_storeWeak function is declared as follows:

id objc_storeWeak(id *location, id value);
Copy the code
Release 3.

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 object address from the Weak table, and clears the object’s record.

What happens to the weak pointer when the object to which the weak reference points is released? When an object is released, the basic flow is as follows:

  • 1.Call objc_release
  • 2.Because the reference count for the object is 0, dealloc is executed
  • 3.In dealloc, the _ objc _ rootDealloc function is called
  • 4.In _ objC _ rootDealloc, object _ dispose function is called
  • 5.Call objc_destructInstance
  • 6.Finally, objC _ clear _ dealLocating is called

Objc _ clear _ deallocating The action is as follows:

  • 1.Gets the address of the deprecated object as a key from the weak table
  • 2.Assign nil to all addresses with weak modifier variables included in the record
  • 3.Delete the record from the weak table
  • 4.Removes the record of discarded objects whose addresses are key values from the reference count table

Difference between assign and weak

  • 1. Can use the assignThe object of OCAnd the weakMust be used for OC objects
  • 2. Weak showThis attributeDefines a kind of"Non-owning relationship". Refers to in the attributeObject is destroyedWhen,Property values automatically empty nil

strong

  • 1. In the ARC environment, as long as aobjectBy aStrong pointer totheobjectitWill not be destroyed.
  • 2. IfThe object is not pointed to by any strong pointer, thenWill be destroyed.
  • 3. By default, allThe instance variablesandA local variableAre allStrong type. To say theStrong typethePointer to theinOn the behaviorwithThe ARCUnder theRetain is more similarthe

copy

Preliminary knowledge

  • Shallow copy
    • Just put the object memory addressThere's an extra quoteThat is, after the copy, twoobjecttheNot only are the values the sameAnd,Object refers to the same memory addressthe
  • Deep copy
    • To copy an objectThe specific content.Copy the endAnd then, of two objectsvalueAlthough it isThe same, butThe memory address pointing to is different.Between two objectsalsoEach other.Mutual interference

The role of the copy

  • 1. InNon-collection class objectIn theImmutable objectforThe copy operation, just justA pointer to copy— Shallow copy,Perform mutableCopy operation, it iscopy– deep copy
  • For 2.immutabletheCopy collection objects, justChanging the pointer, itsThe memory address has not changed;Perform mutableCopy operation.The memory address has changedBut the elementsMemory addressandThere is no change
  • (3) forMutable collection class object, whetherCopy operationorMutableCopy operation, itsThe memory addresses have all changedBut among themNone of the element memory addresses have changed, belong toSingle layer deep copy

Note: When you assign a mutable object to two properties that use different modifiers and change the contents of the mutable object, the strong modifier will follow, but the copy modifier will not change the contents. That's why NSString uses copy modifier

Dynamic library static library difference

Static libraries are linked to object code at compile time, and dynamic libraries are loaded into the code at run time. There is only one copy of the dynamic library, shared by multiple programs. Static libraries will be copied in each app

Pod source code approach to introduce private libraries, packaged into dynamic libraries/static libraries using POD integration steps

  • 1. Run commandsPod lib create Project name
  • 2. Open the. Podspec file and modify the class library configuration (s.public_header_files = ‘Pod/Classes/H ‘// The files that need to be exposed can also be specified as multiple files. Such as: ‘Pod/Classes/YPAPI / * * /.h’,’Pod/Classes/YPBase/YPModel /.h’,’Pod/Classes/YPBase/YPUtils/YPUtils.h’,’Pod/Classes/YPBind/YPViewController/YPCardListController.h’,’Pod/Classes/YPB ase/YPBaseController/YPBaseViewController.h’,’Pod/Classes/**/‘)
  • 3. Go to the Example folder and runpod installHave the Demo project install the dependencies and update the configuration
  • 4. Use a Cocoapods plugincocoapods-packagerTo complete the packaging of the class library
    • To install the package plug-in, run the following command:sudo gem install cocoapods-packager
    • Package, executePodspec --library --forceWhere –library specifies to be packaged as a. A file, otherwise it will be packaged as a. Framework file. –force: indicates mandatory overwriting

    Problem 1: xcode12 and later packaging has a static library arm64 conflict

    • The reason:Apple added the arm64 architecture for emulators that conflicts with the real arm64 architecture

    Fix: If it is manual merge error in Xcode to ignore the architecture, ignore the emulator architecture can be a big push online; If you failed to pack with pod packets, ignore arm64 in pod Spec

Principle of automatic release pool

  • 1. Automatic release pool is made byAutoreleasePoolPageTwo-way linked listBy the way
  • 2. When the object is calledautoreleaseMethod, will be the objectJoin AutoreleasePoolPageThe stack
  • 3. CallAutoreleasePoolPage::popMethod sends a Release message to an object on the stack
  • 4. The auto-release pool is closely related to threads, and each auto-release pool corresponds to only one thread

HTTP is different from HTTPS

  • 1. UseHTTPSThe protocol needs to beCertificate Authority (CA) applies for a CertificateIn general, there are few free certificates and they require some cost
  • 2. The protocol headers are different.httpThe URL to"http://"The HTTPS URL starts with"https://"At the beginning
  • 3.Security is different. HTTP has no security mechanism for data encryption and data integrity verification, while HTTPS uses digital certificates to ensure communication between the two parties
  • 4.The listening port is different. HTTP listens on port 80, while HTTPS listens on port 443
  • 5. When establishing a connection:HTTPS has more of TLS's handshake than HTTP

Why does OC support these dynamic features of runtime?

Objective-c has a number of Dynamic features, which can be seen in three aspects: Dynamic typing, Dynamic binding, and Dynamic loading. Dynamic — something that must not be done until run time

Caton’s principles, how is interface optimization done in the project, and what are the problems with asynchronous rendering?

What’s the problem with asynchronous rendering: the answer is that you can’t see the rendered view layer

Logic for collision detection

– (BOOL)pointInside (CGPoint) Point withEvent (Nullable UIEvent *)event; – (BOOL)pointInside (CGPoint) Point withEvent (Nullable UIEvent *) Event;

// convertPoint relative to aView to point relative toView coordinate system, and return - (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view; // convertPoint fromView to aview and return a coordinate point relative to aview - (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view; // convert the rect relative to the view to the rect relative to the view coordinate system, and return a rect value - (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view; // convert points from aView to view and return a size relative to aView - (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;Copy the code

Determine the code

// This is the origin of the judgment, // [imageView2 pointInside:[imageView3 convertPoint:CGPointMake(imageView3.bounds.origin.x+imageView3.bounds.size.width/2, imageView3.bounds.origin.y) toView:imageView2] withEvent:nil] if ([imageView2 pointInside:[imageView3 ConvertPoint: imageView3. Bounds. Origin toView: imageView2] withEvent: nil]) {[tiplabel setText: @ "collision"]. } else{tiplabel setText:@" no collision "]; }Copy the code

What is the Richter substitution

One of the basic principles of object-oriented design. Richter’s rule of substitution says that wherever a base class can appear, a subclass must appear. LSP is the cornerstone of inheritance reuse. The base class can be reused only when the derived class can replace the base class and the function of the software unit is not affected. The derived class can also add new behaviors on the base class. The Richter substitution principle is a complement to the open – close principle. The key step in implementing the “open – close” principle is abstraction. The inheritance relationship between base class and subclass is the concrete realization of abstraction, so the Richter substitution principle is the specification of the concrete steps to realize abstraction.

The open closed principle

The open-closed principle states that “objects in software (classes, modules, functions, etc.) should be open for extension but closed for modification,” which means that an entity is allowed to change its behavior without changing its source code. This feature is especially valuable in a Productized environment, where changing source code requires code review, unit testing, and the like to ensure product usage quality. Code that follows this principle does not change when it is extended, and therefore does not need the above process.

SD large picture loading scheme

  • 1.Set image caching to prevent image crashes
  • In 2.- (void)didReceiveMemoryWarningIn the methodEmpty diskandMemory cache
  • In 3.- (void)deallocIn the methodClean the cache again

Automatic release pool -AutoReleasePool

When are temporary variables released?

  • 1. If thenormalDown, generallybeyonditsscopeitWill be released immediately.
  • 2. If you willTemporary variableJoined theAutomatic release tankWill,Delay the release ofIn which theRunloop dormancyorAutoreleasepool scopeafterThe release of

AutoreleasePool principle

  • 1. Automatically release the poolNature isaAutoreleasePoolPage structure object, it is aThe stack structure stores pages, each oneAutoreleasePoolPageAre based onTwo-way linked listtheIn the form of connection
  • 2. Automatically release the poolThe pressure of stackandOut of the stackMainly throughThe structure of the bodytheThe constructorandDestructor callswithThe underlyingtheobjc_autoreleasePoolPushandobjc_autoreleasePoolPop, is actually calledAutoreleasePoolPage push and popTwo methods
  • 3. Each callPush the operationIn fact, iscreateaNew AutoreleasePoolPageAnd theAutoreleasePoolPageThe specific operation ofInsert a POOL_BOUNDARYAnd returnInsert the memory address of POOL_BOUNDARY. whilePush is handled internally by calling the autoreleaseFast method, mainly in the following three cases
    • When the page exists and is not satisfied, the add method is called to add the object to the next pointer of the page and increment next
    • When a page exists and is full, call autoreleaseFullPage to initialize a new page, and then call the Add method to add the object to the page stack
    • When the page does not exist, call autoreleaseNoPage to create a hotPage, and then call the Add method to add the object to the Page stack
  • 4. When you performPop operationwhenPassing in a valuethevalueisPush the operationtheThe return value.The memory address token of POOL_BOUNDARY. soPop insidetheimplementationisAccording to the tokenfindPage of the sentinel objectAnd then useobjc_releaseThe release ofObject before tokenAnd,Put the next pointer in the correct position

Can AutoreleasePool be nested?

  • 1.Can be nestedIts purpose is to be able toControl applicationtheThe peak of memoryMake it not too high
  • 2. Nesting is possible becauseAutomatic release tankBased onStack for the nodeThrough theTwo-way linked listIn the form ofThe connectionandIt's one to one for threads
  • 3. Automatically release the poolMultilayer nestedActually,Is the incessant pushs sentinel objectIn theWhen the popWill,First release the insideThe,And release the outsidethe

Which objects can be added to AutoreleasePool? Alloc creation ok?

  • 1.Objects generated using the new, alloc, copy keywordsandRetained objectNeed to beHand release.Will not be added to the automatic release pool
  • 2. Set toautoreleasetheObjects do not need to be released manuallyWill,Go directly to the automatic release pool
  • All 3.autoreleaseobjectIn theOut of scopeAfter that, it’s going to beAutomatically addtoRecently createdtheAutomatic release tankIn the

When is AutoreleasePool released?

  • 1.The App launchedAfter, apple inThe main thread RunLoopTwo Observers were registered, itsThe callback is _wrapRunLoopWithAutoreleasePoolHandler ().
  • 2.The first Observer monitors eventsisEntry(about to enter Loop), itsThe automatic release pool is created by calling _objc_autoreleasePoolPush() inside the callback. itsThe order is - 2147483647.Highest priorityTo ensureCreating the release pool takes place before any other callbacks
  • 3.The second Observer monitors two events: BeforeWaiting(Ready to go to sleep)Call _objc_autoreleasePoolPop ()_objc_autoreleasePoolPush() 'frees the old poolandCreate a new pool;Exit(will Exit Loop)whenCall _objc_autoreleasePoolPop ()toRelease Automatic release pool. thisObservertheorder 2147483647.Lowest priority, ensure theThe release of the poolOccurred after all the other callbacks.

Relationship between Thread and AutoreleasePool

  • 1.Each thread, includingThe main threadinAll maintenanceHis ownAutomatically free the pool stack structure
  • 2. NewAutomatic release tankIn thecreateThat will beAdd to the top of the stack; whenAutomatic release pool destruction, fromThe stack to remove
  • (3) forThe current threadSay, willAutomatic releasetheObject into the automatic release pooltheTo the top of the stack; inThread to stopwhenSelf-releasewithThe thread associationtheAll automatic release pools

conclusion

Each thread has an autofree pool stack structure associated with it. New pools are pushed to the top of the stack when they are created, pools are removed when they are destroyed, free objects are pushed to the top of the stack for the current thread, and the associated autofree pool is automatically released when the thread stops

Relationship between RunLoop and AutoreleasePool

  • 4.The main programtheRunLoopinBefore each event loopWill,Automatically create an autoreleasePool
  • 5. And will be thereEnd of event loopWhen,Execute drain operation.Release the objects in it