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 replacement
It's constantly taking up memory
Const is stored in the data segmentThere is only one copy
More efficient - Define can define some simple functions, const can’t
What’s the difference between block and weak?
- __block whether in ARC or MRC mode
all
Can be used,can
Modify the object,Can also be
Decorates the base data type - __weak
only
Used in ARC mode,only
Modify object (NSString),Can't
Decorates 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 case
weak
Key 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 destroyed
Wild pointer
If 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
- 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 destroyed
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]
not
Thread-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, then
The default
It’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 will
automatic
Add these two methods for you - @dynamic tells the compiler that setter and getter methods for a property are defined by
User 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 you
There is no
It provides at sign setter methods and at sign getter methods,That's fine when you compile it
But 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
- So if a property is declared at sign dynamic var, then you
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 situation
Don't
Autosynthesis- 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 be
Use @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, generally
Don't recommend
To do so, it is recommended to use member variables automatically generated by the system
- When you override both the setter and getter, the system does not generate ivAR. There are two options
How to use the copy keyword?
- NSString, NSArray, NSDictionary, and so on often use the copy keyword because they have counterparts
The 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 ARC
Write it or not
Copy 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 brings
Performance issues
You 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 class
Only 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 method
Don't
Automatically inherited by the class
- +(void)initialize;
- This method is also called the first time the class is used, so is Initialize
Lazy loading
- This method is also called the first time the class is used, so is Initialize
- 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 are
optional
And only whenTo achieve the
When theyBefore it gets called
- What they have in common: Both methods
It 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 class
Being observed for the first time
, the system will be runningdynamic
To createA derived class of this class
Override 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 named
NSKVONotifying_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 be
Used inA collection of objects
On orCollection properties of ordinary objects
on- 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