The difference between category and extension

  • A class extension has no class name and is a special kind of classification
  • Classes can only extend methods (attributes are only declared, not really implemented), and class extensions can extend attributes, member variables, and methods

What’s the difference between define and const constant?

  • Define is replaced during preprocessing and const constants are used during compilation
  • Macros don’t do type checking, just substitution, const constants have data types and do type checking
  • Define cannot be debugged, const constants can be debugged
  • The constant defined by DEFINE is run after the replacementIt's constantly taking up memoryConst is stored in the data segmentThere is only one copyMore efficient
  • Define can define some simple functions, const can’t

What’s the difference between block and weak?

  • __block whether in ARC or MRC modeallCan be used,canModify the object,Can also beDecorates the base data type
  • __weakonlyUsed in ARC mode,onlyModify object (NSString),Can'tDecorates the base data type
  • ** Block objects can be reassigned within a block, but **weak objects cannot

The static keyword is used

  • The static variable in a function (method) has the scope of the function body. The memory of the static variable is allocated only once, so its value remains the same the next time it is called.
  • Static global variables in a module can be accessed by functions inside the module, but not by other functions outside the module.
  • A static function in a module can only be called by other functions in the module. The use of this function is restricted to the module in which it was declared.
  • A static member variable in a class is owned by the entire class. There is only one copy of all objects in the class.
  • The static member function in a class is owned by the whole class. This function does not receive the this pointer, so it can only access the static member variable of the class

The difference between heap and stack

  • In terms of management style
    • For the stack, it is automatically managed by the compiler, without our manual control;
    • In the case of the heap, the release is controlled by the programmer and is prone to memory leaks.
  • In terms of application size and size
    • The stack space is small
    • The heap control is large
  • In terms of data storage
    • Stack space generally stores basic types, the addresses of objects
    • Heap space generally stores objects themselves, block copies, etc

Style error correction

  • The modified code

    typedef NS_ENUM(NSInteger, CYLSex) { CYLSexMan, CYLSexWoman };

    @interface CYLUser : NSObject

    @property (nonatomic, copy, readonly) NSString *name; @property (nonatomic, assign, readonly) NSUInteger age; @property (nonatomic, assign, readwrite) CYLSex sex;

    • (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;
    • (instancetype)initWithName:(NSString *)name age:(NSUInteger)age;
    • (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;

    @end

What mechanism does Objective-C use to manage object memory?

  • MRC manual reference counting
  • ARC automatic reference counting, now usually ARC
  • RetainCount is used to determine if an object needs to be released. Every time the runloop is run, the object’s retainCount is checked. If the retainCount is 0, the object has no further use and can be released

In what ways does ARC help developers manage memory?

  • Through the compiler at compile time, insert similar memory management code

What problem was ARC created to solve?

  • ARC: Automatic Reference Counting Automatic reference counting
  • Understand the disadvantages of MRC
    • In the MRC era when we wanted to free a heap, we first made sure that all Pointers to the heap were released
    • To free a pointer to the same heap, first determine which Pointers to the same heap can be freed only once.
    • When modularizing operations, objects can be created and used by multiple modules without knowing who will eventually release them
    • In multi-threaded operations, it is uncertain which thread will be used up last
  • To sum up, MRC has many disadvantages, which can easily cause memory leakage and bad memory problems. At this time, Apple tried to solve this problem, thus creating ARC

Will there still be memory leaks under ARC?

  • Circular references can cause memory leaks
  • Bridging objective-C objects to CoreFoundation objects can also cause memory leaks if mismanaged
  • Objects in CoreFoundation are not managed by ARC and need to be released manually by the developer

When is the weak keyword used, and how is it different from assign?

  • First of all, what is the caseweakKey words?
    • In ARC, circular references are usually addressed by having one end use weak, such as the delegate delegate attribute. The delegate attribute can also be assigned
    • It has already been strongly referenced once by itself, so there is no need to strongly reference it again. In this case, weak is also used. Custom IBOutlet control properties usually use weak as well. Of course, you can also use strong, but weak is recommended
  • Differences between weak and assign
    • Weak policy When the object indicated by the attribute is destroyed, the system will point the pointer of the attribute object modified by weak to nil. There is no problem in OC sending messages to nil. This is created when the assign policy is used so that the pointer to the assign object still points to the original object after the object to which the attribute is assigned is destroyedWild pointerIf a message is sent to this object, it may cause the program to crash
    • Assigin can be used to modify non-OC objects, while weak must be used for OC objects

What is the nature of @property?

  • The @property is basically the compiler automatically generates ivAR member variables, getters, setters during compilation

How are ivar, getters, and setters generated and added to this class?

  • Use “Autosynthesis”

  • The process is automatically synthesized by the compiler at compile time, so the source code for these synthesized methods is not available in the editor

  • In addition to generating getters and setters, the compiler also automatically adds member variables to the class (preceded by an underscore to the property name as the instance variable name)

  • To figure out how properties are implemented, he decompiles the associated code, and he generates roughly five things, right

    // The attribute's offset, which is hardcode, OBJC_IVAR_$Class name $Property name // Setters and getters for methods // List of member variables ivar_list // List of methods method_list // List of properties prop_listCopy the code
    • Each time you add an attribute, the system adds a description of the member variable to the ivar_list
    • Add a description of setter and getter methods to method_list
    • Add an attribute description to the prop_list
    • Calculates the offset of this property in the object
    • Then the corresponding implementation of setter and getter methods is given. In setter methods, the value is assigned from the offset position, and in getter methods, the value is assigned from the offset position. In order to be able to read the correct number of bytes, the pointer type of the offset of the system object is typed forcefully

How do you use @property in @protocol and category

  • Using property in protocol only generates setter and getter method declarations, and we use properties in the hope that objects that comply with our protocol will implement the property

  • Using @property for a category also generates only setter and getter declarations. If we really need to add properties to a category, we need to use two functions at run time

    objc_setAssociatedObject objc_getAssociatedObject

What modifiers can follow @property?

  • Atomicity –nonatomic qualities

    • If you do not write, the default is atomic (the system will automatically add synchronization lock, which affects performance).
    • Specify nonatomic as much as possible in iOS development to help improve performance
  • Read/write permission — ReadWrite, Readooly

  • Memory management semantics -assign, strong, weak, unsafe_unretained, and copy

  • Method names –getter=, setter=

    @property (nonatomic, getter=isOn) BOOL on;

    // setter= This is not commonly used and is not recommended. So I’m not going to write it here

  • Nonnull, NULl_resettable,nullable

Is using atomic necessarily thread-safe?

  • No, the original meaning of the atomic statement is that the access method of the property is thread-safe, but it does not guarantee that the entire object is thread-safe.
  • For example: declare an NSMutableArray atomic property called stuff, where self.stuff and self.stuff = othersulf are thread-safe. Instead, use [self.stuff objectAtIndex:index]notThread-safe. Mutex is required to ensure thread-safe

What does @synthesize and @dynamic do

  • At sign property has two words, at sign synthesize, and at sign dynamic. If at sign synthesize and at sign dynamic don’t write, thenThe defaultIt’s @syntheszie var = _var;
  • The semantics of the at sign synthesize is that if you don’t implement setter and getter methods manually, then the compiler willautomaticAdd these two methods for you
  • @dynamic tells the compiler that setter and getter methods for a property are defined byUser implementation, not automatically generated (of course, you only need to provide getters for readonly properties)
    • So if a property is declared at sign dynamic var, then youThere is noIt provides at sign setter methods and at sign getter methods,That's fine when you compile itBut when the program runs to instance.var = someVar, the program will crash due to the absence of setter methods. Or when someVar = instance.var is run, it will also crash due to the lack of getter methods.Compile time is fine, and the corresponding method is executed at run time, which is called dynamic binding

In ARC, what are the default keys when you do not explicitly specify any attribute keys?

  • Basic data: Atomic,readwrite,assign
  • Normal OC objects: atomic,readwrite,strong

What are the rules for @synthesize instance variables? If the property name is foo and there is an instance variable named _foo, will the new variable be synthesized automatically?

  • Answer the second question first: no

  • The rules for @synthesize a member variable have the following:

    • If a member variable name is specified, a member variable with the specified name is generated

    • No longer generated if the member already exists

    • If you specify at sign synthesize foo; A member variable named foo is generated, i.e., a member variable with the same property name is automatically generated

      @interface XMGPerson : NSObject @property (nonatomic, assign) int age; @end@implementation XMGPerson @end@implementation XMGPerson @end@implementation XMGPerson @end@implementation XMGPerson @endCopy the code
    • If at sign synthesize foo = _foo; Member variables will not be generated

What other scenarios does @synthesize use after you have automatic synthetic property instance variables?

  • First of all, what is the situationDon'tAutosynthesis
    • When I overwrite both the setter and the getter
    • Overrides the getter for a read-only property
    • When you use at sign dynamic
    • All attributes defined in @protocol
    • All properties defined in the category
    • Overloaded properties, when you override a property in a subclass,Must beUse @synthesize to manually synthesize IVar
  • Application scenarios
    • When you override both the setter and getter, the system does not generate ivAR. There are two options
      • Manually create ivAR
      • At sign synthesize foo = _foo; , associate @property with Ivar
    • Can be used to modify member variable names, generallyDon't recommendTo do so, it is recommended to use member variables automatically generated by the system

How to use the copy keyword?

  • NSString, NSArray, NSDictionary, and so on often use the copy keyword because they have counterpartsThe variable type: NSMutableString, NSMutableArray, NSMutableDictionary, to ensure that the value of an attribute in an object does not change unintentionally, you should copy the value of a new attribute when setting it to protect encapsulation
  • Blocks also often use the copy keyword
    • Block use of copy is a “legacy” from MRC, where the block inside a method is on the stack and copy can be used to put it on the heap.
    • In the ARCWrite it or notCopy is the same as strong for blocks, but copy is recommended because it tells the caller that the compiler automatically copies the block.

Nsstrings (or NSArray, NSDictionary) declared with @property often use the copy keyword. Why? What problems might arise if you use the strong keyword instead?

  • Because a parent pointer can point to a subclass object, the purpose of using copy is to keep the properties of this object unaffected by the outside world. Whether I am passed a mutable object or an immutable object, I am holding an immutable copy.
  • If we use strong, the property may point to a mutable object, and if the mutable object is modified externally, the property will be affected.

Copy,

  • Shallow copy: In shallow copy operations, pointer copies are made for each layer of the object being copied.

  • One-level-deep copy: During a deep copy operation, at least one layer of the object to be copied is the deep copy.

  • Real-deep copy: In a full copy operation, the object is copied for each layer of the copied object.

  • Copy and mutableCopy of a non-collection object

    [Immutable object copy] // Shallow copy [Mutable object copy] // Deep copy [mutable object copy] // Deep copy [mutable object copy] // Deep copyCopy the code
  • Copy and mutableCopy of a collection class object

    [Immutable object copy] // Shallow copy [Immutable object mutableCopy] // Single-layer deep copy [Mutable object copy] // Single-layer deep copy [mutable object mutableCopy] // Single-layer deep copyCopy the code
  • It is important to note here that the content copy of the collection object is limited to the object itself; the object elements are still pointer copies

@ Property (copy) NSMutableArray *array;

  • Because the copy policy copies an immutable object, but uses it as a mutable object, it is easy to crash the program
  • There is also a problem here. This property uses a synchronous lock, which generates some extra code at creation time to help write multithreaded programs, which bringsPerformance issuesYou can save this small but unnecessary overhead by declaring nonatomic,Nonatomic should be used instead of atomic in iOS development

How do I make copy modifiers available to custom classes? How do I override a setter with the copy keyword?

  • If you want to copy your own objects, you need to implement the NSCopying protocol. NSCopyiog and NSMutableCopying should be implemented at the same time if the object is mutable and immutable

    // Implement immutable version copy

    • (id)copyWithZone:(NSZone *)zone;

    // Implement mutable version copy

    • (id)mutableCopyWithZone:(NSZone *)zone;

    // override setter with copy keyword

    • (void)setName:(NSString *)name

    { _name = [name copy]; }

+(void)load; +(void)initialize; What’s the use?

  • +(void)load;
    • When class objects are introduced into a project, the Runtime sends a Load message to each of them
    • The load method is introduced for every class or even classOnly called once, the order of invocation: the parent class takes precedence over the subclass, and the subclass takes precedence over the classification
    • Since the load method is called once when the class is imported, which is often the best time to change the behavior of the class, you can use methods such as Method Swizlling to modify the existing method
    • The load methodDon'tAutomatically inherited by the class
  • +(void)initialize;
    • This method is also called the first time the class is used, so is InitializeLazy loading
  • Conclusion:
    • In Objective-C, the Runtime automatically calls these two methods for each class
    • +load is called when the class is initially loaded
    • + Initialize is called before the first call to the class method or instance method of the class
    • The two methods areoptionalAnd only whenTo achieve theWhen theyBefore it gets called
    • What they have in common: Both methodsIt will only be called once

What are the differences between Foundation objects and Core Foundation objects

  • The Foundation framework is implemented using OC and Core Foundation is implemented using C

  • Conversion between Foundation objects and Core Foundation objects: commonly known as bridging

    • ARC environment bridge keywords:

      // Across Foundation and Core Foundation objects __bridge // Across Foundation and Core Foundation objects __bridge_retained // Core The Foundation object becomes the Foundation object __bridge_transferCopy the code
      • Foundation objects become Core Foundation objects

        • Use __bridge

          • If __bridge is used, it simply gives the strOC address to strC and does not transfer ownership of the object. That is, if __bridge is used, then if strOC is released, the strC cannot be used

          • Note: Under ARC conditions, strC can be released without active release if __bridge is used, since ARC automatically manages strOC and strC

            NSString *strOC1 = [NSString stringWithFormat:@”abcdefg”]; CFStringRef strC1 = (__bridge CFStringRef)strOC1; NSLog(@”%@ %@”, strOC1, strC1);

        • Use __bridge_retained bridge

          • Using __bridge_retained bridge transfers ownership of the object to strC, meaning strC can use it even if strOC is freed

          • Note: Under ARC, if __bridge_retained bridge is used, strC must be freed manually, because the bridge has already transferred ownership of the object to strC, and C stuff is not exempt from ARC

            NSString *strOC2 = [NSString stringWithFormat:@”abcdefg”]; // CFStringRef strC2 = (__bridge_retained CFStringRef)strOC2; CFStringRef strC2 = CFBridgingRetain(strOC2); CFRelease(strC2);

      • Core Foundation object becomes Foundation object

        • Use __bridge

          • If __bridge is used, it simply gives the ADDRESS of the strC to the strOC and does not transfer ownership of the object

          • That is, if __bridge is used, then if strC is released,strOC cannot be used

            CFStringRef strC3 = CFStringCreateWithCString(CFAllocatorGetDefault(), “12345678”, kCFStringEncodingASCII); NSString *strOC3 = (__bridge NSString *)strC3; CFRelease(strC3);

        • Use __bridge_transfer to bridge

          • If the __bridge_transfer bridge is used, it transfers ownership of the object to strOC, meaning that strOC can use it even if the strC is released

          • If the __bridge_transfer bridge is used, it will automatically release the strC, meaning we will not have to release the strC manually in the future

            CFStringRef strC4 = CFStringCreateWithCString(CFAllocatorGetDefault(), “12345678”, kCFStringEncodingASCII); // NSString *strOC = (__bridge_transfer NSString *)strC; NSString *strOC4 = CFBridgingRelease(strC4); // This sentence is equivalent to the previous sentence

    • MRC environment: direct strong rotation

      -(void)bridgeInMRC {// Convert Foundation object to Core Foundation object, NSString *strOC1 = [NSString stringWithFormat:@" XXXXXX "]; CFStringRef strC1 = (CFStringRef)strOC1; NSLog(@"%@ %@", strOC1, strC1); [strOC1 release]; CFRelease(strC1); // Convert Core Foundation object to Foundation object, Can be directly casts CFStringRef strC2 = CFStringCreateWithCString (CFAllocatorGetDefault (), "12345678", kCFStringEncodingASCII); NSString *strOC2 = (NSString *)strC2; NSLog(@"%@ %@", strOC2, strC2); [strOC2 release]; CFRelease(strC2); }Copy the code

AddObserver: forKeyPath: options: context: what are the effect of various parameters, which need to implement in the observer method to obtain KVO callback?

/ * * 1. The self. The person: Object to listen on 2. Parameter Description 1> Observer, the object responsible for handling the listening event 2> Properties to listen on 3> Options to observe (observe new, old, or both values) 4> Context, used to pass data, Can use the context to distinguish different listening * / [self. The person addObserver: self forKeyPath: @ "name" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"]; /** * when the value of one of the monitored attributes changes, the @param keyPath attribute name is called ** @param object attribute object * @param change attribute modification (attribute original value, attribute latest value) ** @param context passes the same context data as when listening, Context can be used to distinguish different listeners */ - (void) observeforkeypath :(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change Context :(void *)context {NSLog(@"%@ object %@ property changed: %@", object, keyPath, change); }Copy the code

KVO internal implementation principles

  • KVO is implemented based on the Runtime mechanism
  • When the property object of a classBeing observed for the first time, the system will be runningdynamicTo createA derived class of this classOverride setter methods for any observed properties in the base class in this derived class. Derived classes implement true in setter methods that are overriddenA notification mechanism
  • If the original class is Person, the generated derived class is namedNSKVONotifying_Person
  • Each class object has an ISA pointer to the current class. When a class object is observed for the first time, the system secretly points the ISA pointer to a dynamically generated derived class, thus performing setter methods of the derived class when assigning values to monitored properties
  • Key-value observation notifications depend on NSObject’s methods: willChangeValueForKey: and didChangevlueForKey:; Before an observed property changes, willChangeValueForKey: must be called, which records the old value. When change happens, didChangeValueForKey: is called, which in turn observeValueForKey: ofObject: change: context: will be invoked.
  • Note: The KVO implementation mechanism also secretly overrides the class method to make us think we are using the current class, so as to hide the generated derived classes

How do I manually trigger a value’s KVO

  • Automatic trigger scenario: before registering KVO, set an initial value, after registering, set a different value, can trigger

  • Want to know how to trigger manually, must know the principle of automatic trigger KVO, see the description above

  • Manual trigger demo

    @property (nonatomic, strong) NSDate *now;

    • (void)viewDidLoad

    { [super viewDidLoad];

    // "Manually trigger self.now KVO", mandatory. [self willChangeValueForKey:@"now"]; // "Manually trigger self.now KVO", mandatory. [self didChangeValueForKey:@"now"];Copy the code

    }

If a class has an instance variable NSString *_foo, does setValue:forKey: call foo or _foo as the key?

  • Can be

How is the set operator in KVC’s keyPath used?

  • Must beUsed inA collection of objectsOn orCollection properties of ordinary objectson
  • The simple set operators are @avg, @count, @max, @min, @sum

Must the keyPath of KVC and KVO be attributes?

  • It can be a member variable

The end of the article recommended: iOS popular anthology & video analysis

  • 1.Underlying iOS technology

  • 2.IOS Reverse Protection

  • 3.Big factory interview question + underlying technology + reverse security +Swift