All source code is based on objC-Runtime-objC.680
Recently, the series of articles sorted out can not be sent out, the review can not pass = = have the need of small partners move to iOS interview memo later nuggets can update me again = =
preface
“IOS interview Questions Memo (1) – Attribute keywords” is about iOS attribute keywords related knowledge points and interview questions sorted out, the degree of difficulty is not differentiated, that is, the default is the content must be mastered. The content of this article will continue to be sorted out and updated and improved. If there is any incorrect understanding, please inform the gods passing by. Github source address can be detected by the directory
directory
Deep copy and shallow copy
1. What are the copy methods of OC objects? (What are shallow and deep copies?)
2. Are the copies and mutableCopy of the OC object shallow or deep copies respectively?
3. Are the copy and mutableCopy of the custom object shallow or deep copy respectively?
4. Check the type of the current deep copy. (the difference is single layer deep copy or full deep copy), the conversion of 2 deep copy types?
5. Since the object’s mutableCopy is a deep copy, why change the dataArray2 and dataArray3? How to solve this problem?
6. The code as shown in the figure below: initWithArray: copyItems: YES can only in a layer of deep copy, for the second layer or more layers is invalid. What if you want the object to be a deep copy at every level?
Attribute keywords
1. Do common basic types correspond to Foundation data types?
2. Define the format of the attribute? (In what order are modifiers when defining attributes?)
ARC is the default @property property.
4. What are the read and write permission keywords of attributes?
5. What does the atomic operation keyword of the attribute mean?
6. What is the meaning of the memory management keyword of the property?
7. Assign and weak compare? What are the usage scenarios?
8. What keywords should be used to decorate the delegate?
9. If the weak pointer points to an object, why is the weak pointer automatically set to nil when the object is dealloc or deprecated? (How is the weak variable handled when an object is released or discarded?)
10. Why can assign modify primitive data types? (Why assign does not have wild Pointers to the base data type?)
11. Compare the modifiers strong and weak?
12. How to use the strong and copy keywords?
13. What’s wrong with the declaration of the following attributes? If you must define it this way, how do you make it right?
@property (nonatomic, copy) NSMutableArray *mutableArray;
Copy the code
14. What’s wrong with the declaration of the following attributes? If you must define it this way, how do you make it right?
@property (nonatomic, strong) NSArray *array;
Copy the code
15. Why does the @property attribute use copy to modify immutable objects and strong to modify mutable objects? 16. Why is the copy keyword used to modify block? 17. MRC how to override setter methods for retain decorates variables? What is the purpose of unequal judgment?
The body of the
Deep copy and shallow copy
1. What are the copy methods of OC objects? (What are shallow and deep copies?)
OC objects (collection type and non-collection type) can be copied in two ways: shallow copy and deep copy.
- Shallow copy: A pointer copy, in which the Pointers of the source and replica objects point to the same region.
- Deep copy: A copy of content, in which the source object and the replica object have Pointers to two different regions.
Deep copy includes single-layer deep copy and full deep copy.(Refer to interview questions 4, 5 and 6 for details)- Single layer deep copy: For the copy object itself, this layer is a deep copy, and all objects in it are shallow copies.
- Full deep copy: Deep copy for the replica object itself and all objects in it.
Shallow copy and deep copy differences:
- Whether new memory space is opened up
- Whether reference counts are affected
Return to the directory
2. Are the copies and mutableCopy of the OC object shallow or deep copies respectively?
- Copy and mutableCopy for mutable objects (collection/non-collection types) are deep copies.
- Copy of immutable objects (collection/non-collection types) is a shallow copy, and mutableCopy is a deep copy.
- The copy method returns immutable objects.
1). Copy and mutableCopy of a mutable object (collection type/non-collection type) are deep copies.
2). Copy of an immutable object (collection type/non-collection type) is a shallow copy, and mutableCopy is a deep copy.
Return to the directory
3. Are the copy and mutableCopy of the custom object shallow or deep copy respectively?
Copy and mutableCopy of a custom object are both deep copies. Custom objects comply with the NSCopying and NSMutableCopying protocols to implement copyWithZone: and mutableCopyWithZone: methods.
1). The copy of a custom object is a deep copy: the copy of a custom object must comply with the NSCopying protocol and implement copyWithZone:.
- Comply with the NSCopying protocol
- Implement the CopyWithZone method
- The copy of a custom object is a deep copy.
2). The mutableCopy of a custom object is a deep copy: the mutableCopy of the custom object is implemented in compliance with the NSMutableCopying protocol, and the mutableCopyWithZone: method is implemented.
- Comply with the NSMutableCopying protocol
- Implement the mutableCopyWithZone method
- Custom object implementation of mutableCopy, is a deep copy.
Return to the directory
4. Check the type of the current deep copy. (the difference is single layer deep copy or full deep copy), the conversion of 2 deep copy types?
- Single layer deep copy: For the copy object itself, this layer is a deep copy, and all objects in it are shallow copies.
- Full deep copy: Deep copy for the replica object itself and all objects in it.
Implementation method:
- Single-layer deep copy: use the initWithArray:copyItems: method (set the second parameter to YES).
- Full deep copy: Archive and file to achieve full deep copy. For example: dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject: dataArray2]].
Return to the directory
5. Since the object’s mutableCopy is a deep copy, why change the dataArray2 and dataArray3? How to solve this problem?
Question (1). The object’s mutableCopy is a deep copy, so why change dataArray2 and dataArray3?
dataArray3 = [dataArray2 mutableCopy]; MutableCopy just copies the array dataArray2 itself, but the string objects inside it are not copied. The string objects in dataArray2 and dataArray3 share the same copy.Copy the code
Question (2). How to solve this problem?
Use the initWithArray:copyItems: method with the second parameter set to YES. If you create a deep copy of the collection in this way, a copyWithZone: message is sent to each object in the collection. If the objects in the collection have the NSCopying protocol, they are copied deep into the new collection, which is the sole owner of the copied objects. If the objects are not using the NSCopying protocol, trying to copy them in this way will result in a runtime error. However, copyWithZone: makes a shallow copy. This type of copy can only produce one deep copy, not the second or more layers.
dataArray3 = [[NSMutableArray alloc] initWithArray:dataArray2 copyItems:YES]; Because the string objects in dataArray2 already comply with the NSCopying protocol, they will be copied deep into dataArray3, which is the sole owner of the copied objects. The string objects in dataArray2 and dataArray3 are different.Copy the code
Return to the directory
6. The code as shown in the figure below: initWithArray: copyItems: YES can only in a layer of deep copy, for the second layer or more layers is invalid. What if you want the object to be a deep copy at every level?
Use archiving and archiving to achieve a full deep copy of an object.
dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]];
Copy the code
Return to the directory
Attribute keywords
1. Do common basic types correspond to Foundation data types?
When declaring an attribute, try to use the data types of the Foundation framework to make your code more consistent. The mapping between basic types and Foundation data types is as follows:
- int -> NSInteger
- unsigned -> NSUInteger
- float -> CGFloat
- Animation time -> NSTimeInterval
Return to the directory
2. Define the format of the attribute? (In what order are modifiers when defining attributes?)
The following format is recommended for defining attributes
@property (nonatomic, readwrite, copy) NSString *name;
Copy the code
Property modifiers should be in the following order: atomic operations, read and write permissions, and memory management. Reasons: 1. Properties are easier to correct and read. 2. When modifying modifiers of an attribute, search for modifiers to be modified from right to left. 3. The modifiers that are most likely to change these properties from the far right, in order of probability from high to low, are: Memory management > read and write permissions > atomic operations.
Return to the directory
ARC is the default @property property.
- For basic data types: atomic, readwrite, assign
- For normal Objective-C objects: atomic, readwrite, strong
Return to the directory
4. What are the read and write permission keywords of attributes?
Read and write access
- Readwrite: readable and writable, default modifier. Getters and setters are automatically generated.
- Readonly: read-only. Only getters are generated, not setters.
Return to the directory
5. What does the atomic operation keyword of the attribute mean?
Atomic operation: The atomicity of a property can be interpreted as thread safety.
-
Atomic: Atomicity, synchronization lock, default modifier. Using atomic degrades performance and is not necessarily thread-safe. Other locking mechanisms are needed if thread safety is to be maintained.
-
Nonatomic: Nonatomic, not useful for synchronous locking. Properties are basically set to nonatomic when declared. Using nonatomic can improve access performance.
Atomic uses a synchronous lock, which generates some extra code at creation time to aid in writing multithreaded programs, which can cause performance problems. You can save on this small but unnecessary overhead by declaring the nonatomic keyword. In general, attributes are not required to be “atomic” because they do not guarantee “thread safety” and a deeper locking mechanism is required for thread-safe operations. For example, if a thread reads a property value several times in a row and another thread overwrites the value at the same time, it will still read different property values even if the property is declared atomic.
Extensions: How to keep threads safe?
Thread-safe: Code that allows simultaneous execution by multiple threads without error is thread-safe code. Thread-safe code does not contain race conditions. A race condition is raised when multiple threads update a shared resource simultaneously. To ensure iOS thread security, the following methods are commonly used: (1) @synchronized (2) NSLock (3) dispatch_semaphore_t (4) OSSpinLock Other methods are as follows: NSConditionLock (7) NSCondition (8) pthread_mutex (9) pthread_mutex (recursive)Copy the code
Return to the directory
6. What is the meaning of the memory management keyword of the property?
- Assign: A simple assignment operation for the scalar type.
- Strong: holds the relationship, keeps the new value, releases the old value, and sets the new value.
- Weak: Non-owning relationship. When the owning object is destroyed, the property is emptied.
- Assign: Non-ownership relationship. If the object to which the attribute refers is assigned is destroyed, the attribute will not be emptied.
- Unsafe_unretained: Similar to assign, this attribute applies to the object type and is not owned. If the object specified by the attribute is destroyed, the attribute cannot be deleted.
- Copy: Copies the new value instead of keeping it.
Note: 1. Unsafe_unretained: perform a simple assignment for the attribute. Setter methods neither retain the new value nor release the old value, that is, do not change the reference count. Unsafe_unretained modifies only OC objects. And when the object is destroyed, the occurrence of wild pointer will also cause the program crash. 2. Retain: Retain is less used in the ARC environment but has the same effect as strong in MRC.
Extension: Use time?
Return to the directory
7. Assign and weak compare? What are the usage scenarios?
Assign: Performs a simple assignment to the attribute. When setting a new value for a property, setter methods neither retain the new value nor release the old value, that is, do not change the reference count.
- Decorates basic data types, such as int, bool, and so on
- Decorates an object type without changing its reference count
- Produces wild Pointers
Weak: Performs a simple assignment to the attribute. When setting a new value for a property, setter methods neither retain the new value nor release the old value, that is, do not change the reference count.
- Modifying an object type without changing its reference count is mostly used to solve the circular reference problem
- The regret is automatically set to nil when the object is released
7.1 Comparison of Assign and Weak
Similarities: There is no effect on the reference count of objects, that is, they are weak references.
Differences: 1. Different types of modified objects:
- Weak can only modify OC objects (such as UIButton, UIView, etc.).
- Assign assigns basic data types (NSInteger, NSUInteger, CGFloat, NSTimeInterval, int, float, BOOL, etc.) and OC objects. Don’t do it). Note: Using assign to modify an OC object could cause the program to crash, so assign is best used to modify only basic data types.
2. Assign the value in different ways: weak Copies the reference, and assign copies the data.
3. After the object is destroyed, its status is different: Weak is automatically nil, and assign remains the same. Note: When the memory pointed to by the weak pointer is freed, the value of the weak attribute is automatically assigned to nil by the compiler. There are no wild Pointers, i.e. pointing to a nil, and sending messages to nil is fine, so it will not crash due to object destruction. When the memory assigned to the assign pointer is freed, the compiler will not automatically assign nil to the assign attribute. Instead, the compiler will assign a wild pointer to an object that has been destroyed. Therefore, if the object is not destroyed, the program will likely crash by sending a message to the wild pointer. Unsafe_unretained and assign are the same. Officially, it’s recommended to use weak instead of assign if you don’t want to increase the reference count of the held object, as you can see from the header provided by Apple — all delegate modifiers are weak. Wild pointer: not NULL pointer, pointer to “junk” memory.
7.2 When is the Weak keyword Used
1. In ARC, when a circular reference is possible, it is usually resolved by having one end use weak. For example, the delegate delegate attribute. 2. There is no need to strong-reference the weak node after it has been strongly referenced once. In this case, the weak node is also used. For example, the custom IBOutlet control property usually uses weak.
7.3 When Is the Assign Keyword Used
Decorates the base data type
Return to the directory
8. What keywords should be used to decorate the delegate?
- MRC period: Use assign, which does not create circular references but requires manual release.
- ARC: It is best to use weak. If you use assign, you need to release it manually (see example). If there is no write release logic, the delegate object is likely to be invalid when the page is destroyed, causing the program to crash.
// When retain Count of myViewController changes to 0, dealloc. @property(nonatomic, assign) id<NTESAdManagerDelegate> delegate; // MRC - (void)dealloc {myClass. Delegate = nil; [myClass release]; [super dealloc]; } // ARC: assign is used, which requires manual release. - (void)dealloc { [myClasssetDelegate:nil];
}
Copy the code
Return to the directory
9. If the weak pointer points to an object, why is the weak pointer automatically set to nil when the object is dealloc or deprecated? (How is the weak variable handled when an object is released or discarded?) * * *
When the object is discarded, dealloc method will be called in the internal implementation of the removal of a weak reference method, in removing a weak reference method will be abandoned by the hash algorithm to find the positions of the object in a weak reference table to extract it corresponds to a weak reference list pointer array, to the for loop iterates through the array will each weak pointer to nil.
Return to the directory
10. Why can assign modify primitive data types? (Why assign does not have wild Pointers to the base data type?)
The basic data types are allocated on the stack, and the allocation and reclamation of space on the stack are handled by the system, so there is no need for developers to pay attention to the problem of wild Pointers. So assign can modify primitive data types. OC objects are allocated in the heap and need to be released by the developer.
Return to the directory
11. Compare the modifiers strong and weak?
Strong: Setters whose keyword is the strong property (retain property in MRC) automatically release the old value and retain the new value.
Setter methods whose keyword is the weak attribute do not.
Similarities: 1. Only modify OC objects.
Differences: 1. Strong indicates a strong reference, and weak indicates a weak reference.
Return to the directory
12. How to use the strong and copy keywords?
The @property property modifies immutable objects with copy and mutable objects with strong.
Return to the directory
13. What’s wrong with the declaration of the following attributes? If you must define it this way, how do you make it right?
@property (nonatomic, copy) NSMutableArray *mutableArray;
Copy the code
1. When adding, deleting, or modifying elements in mutableArray, the program crashes because it cannot find the corresponding method. Because copy is copying an immutable NSArray object.
The copy keyword should not be used to modify mutable objects. The copy modifier makes a copy of an object in memory, that is, two Pointers to different memory addresses. All the mutable object types provided by the Foundation framework have implemented the NSCopying protocol, so the copy method returns immutable objects. In this case, the copy keyword is used to modify a mutable array, so assignment to this property results in an immutable array of type NSArray. Because it is an NSArray type, that is, it is an immutable array type, so if the attribute is added, deleted, or changed to a mutable array, it will cause crash. Examples of crash code:
@property (nonatomic, copy) NSMutableArray *mutableArray; NSMutableArray *array = [NSMutableArray arrayWithObjects:@1, @2, nil]; self.mutableArray = array; [self.mutableArray removeObjectAtIndex:0]; A crash occurred: -[__NSArrayI removeObject:]: unrecognized selector sent to instance 0x600000039240Copy the code
So, the correct way to write this is:
@property (nonatomic, strong) NSMutableArray *mutableArray;
Copy the code
Answer 2: If you must use copy, you can change it to the following code: although the modified code runs without error, it is not recommended that you use it in normal times!!
@property (nonatomic, copy) NSMutableArray *mutableArray; // override setter methods to make _mutableArray mutable copy - (void)setMutableArray:(NSMutableArray *)mutableArray {
_mutableArray = [mutableArray mutableCopy];
}
- (void )viewDidLoad {
[super viewDidLoad];
NSMutableArray *array = [NSMutableArray arrayWithObjects:@1, @2, nil]; self.mutableArray = array;
[self.mutableArray removeObjectAtIndex:0];
NSLog(@"self.mutableArray:%@", self.mutableArray); } output: self.mutablearray :(2)Copy the code
Return to the directory
14. What’s wrong with the declaration of the following attributes? If you must define it this way, how do you make it right?
@property (nonatomic, strong) NSArray *array;
Copy the code
Answer: 1. The strong keyword should not be used to modify immutable objects. The strong keyword modifies an attribute by strongly referencing it, meaning that two Pointers point to the same memory address. In this case, the strong keyword is used to modify an immutable array, and this attribute refers to a mutable object. When the mutable object is modified externally, the attribute will be affected. Examples of incorrect code for this rule:
NSArray *array1 = @[@1, @2, @3, @4];
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array1];
self.array = mutableArray;
NSLog(@"self.array:%@", self.array);
[mutableArray removeAllObjects];
NSLog(@"self.array:%@", self.array); Output: 2017-12-21 10:56:06.921292+0800 iOS[1281:60000] self. Array :(1, 2, 3) 4) 2017-12-21 10:56:06.921463+0800 iOS[1281:60000] self.array:()Copy the code
The value of array changed, which is not what we expected, so we changed it to:
@property (nonatomic, copy) NSArray *array;
Copy the code
2. If NSArray must be decorated with the strong keyword, the code would look like this. Although the value of array has not changed, it is not recommended that you use!!!!! normally
NSArray *array1 = @[@1, @2, @3, @4];
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array1];
self.array = [mutableArray copy];
NSLog(@"self.array:%@", self.array);
[mutableArray removeAllObjects];
NSLog(@"self.array:%@", self.array); Output: 2017-12-21 10:58:14.837883+0800 iOS[1308:62063] self. Array :(1, 2, 3) 4) iOS[1308:62063] self. Array :(1, 2, 3, 4)Copy the code
Return to the directory
15. Why does the @property attribute use copy to modify immutable objects and strong to modify mutable objects?
Answer questions 13 and 14
-
Modify immutable objects with copy: The copy property makes a copy of the object in memory, that is, two Pointers to different memory addresses. The object types provided by the Foundation framework have implemented the NSCopying protocol, so the copy method returns immutable objects. Even if the source object is mutable (the object used to implement the property is mutable), the copied object does not change accordingly. Ensures that objects can’t be changed unintentionally.
-
Using strong to modify mutable objects: A property modified by strong is a strong reference to the property, that is, two Pointers to the same memory address. If the source object is mutable, the strong modified object also changes.
Return to the directory
16. Why is the copy keyword used to modify block?
Block use of copy is a “legacy” from MRC. In MRC, blocks inside a method are on the stack, and since the reference count is managed manually, copy to the heap to prevent wild pointer errors. In ARC, it doesn’t matter whether you write a block or not. Using copy or strong has the same effect on the block, but it doesn’t hurt to write copy and reminds us that the compiler automatically copies the block. Without a copy, the class’s callers might forget or not know that the compiler automatically copied the block, and they might copy the property values themselves before calling it. This operation is redundant and inefficient.
Return to the directory
17. MRC how to override setter methods for retain decorates variables? What is the purpose of unequal judgment?
@property (nonatomic, retain) id obj; // setmethod - (void)setObj:(id)obj {
if(_obj ! [_obj]; // if (_obj) { _obj = [obj retain]; }}Copy the code
Purpose of unequal judgment: So what we do to prevent an exception is if the obj object that’s passed in happens to be the same _obj object, without waiting for judgment, we release the original object, and we actually release the obj object that’s passed in, there’s a good chance that the OBJ object has been released, Accessing the released object through the obj pointer will cause the program to crash.
Return to the directory
Reference documentation
Copying Collections – iOS dark and light copies
other
IOS Interview Question Memos
IOS Interview Questions Memo (1) – Attributes Keywords iOS interview questions Memo (2) – Memory Management iOS interview questions Memo (3) – Classification and expansion iOS interview questions Memo (4) – Agent and Notification iOS interview questions Memo (5) – KVO and KVC iOS interview questions Memo (6) – – The runtime algorithm