1. What are common attribute modifiers? (Quote from Jane Just Dongdong)
MRC: Nonatomic Atomic assign Retain Copy ReadWrite ReadOnly, etc.
ARC: Nonatomic Atomic Assign Strong Copy ReadWrite ReadOnly Nonull Nullable etc.
1. Assign is a basic data type modifier that does not change the reference count and is automatically released by the stack.
Retain +1 (MRC) +1 (MRC) +1 (MRC)
3. Strong tells the system to keep the object on the heap until there is no pointer to it. Arc to manage reference counts.
Weak reference is a weak reference and does not hold it. In essence, it allocates an attribute that is not held. When the reference destroys the pointer to weak reference, it will be set to nil automatically, which can avoid circular reference.
5. Copy is used to modify the property field of an immutable type to prevent the property of the object from being affected by external factors. nsstring nsarray nsdictionary.
`
classmentObject * object = [[classmentObject alloc] init]; NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"dassd",@"das", nil]; object.array = array; //@property (nonatomic, strong) NSArray *array; Array does not change as the external array changes. It is not the same reference. [array addObject:@"daas"]; for (int i = 0; i<array.count; i++) { NSLog(@"-----%@",array[i]); } for (int I = 0; i<object.array.count; i++) { NSLog(@"%@",object.array[i]); // copy2}Copy the code
`
6. Readwrite Can be read and write, which is the default generated getter setter method.
Readonly tells the compiler not to automatically generate setter methods. Assignment is not allowed.
Nonatomic access, which allows multiple threads to access variables, can lead to unsafe read-write threads, but can improve performance.
Adding an object to an array or removing an object from an array modified by an atomic method is no way to ensure thread-safety. The disadvantage of atomic access is that it underperforms performance and results in slow execution.
10. Nonull Setting property or method parameters cannot be null and cannot be used for primitive data types.
11. Nullabel Sets the property or method parameter to be null.
2. Deep copy and shallow copy? (Blog.csdn.net/weixin_3954…)
A deep copy copies the content. A shallow copy copies the pointer. If A copies B and changes B, it is A shallow copy. If you want to achieve deep copy by yourself, you need to copy layers of traversal. The significance of deep copy is that the data may be manipulated by many people. If one part of the data is modified, it will affect other parts.
1. After the immutable NSString is copied from the object, the generated object points to the same address as the original object, which is a shallow copy. Objects generated by mutableCopy point to a different address from the original object and are deep copies.
2. Mutable string NSMutableString either from copy or mutableCopy, the generated objects point to different addresses.
- (void)testStringCopy {
NSString *str = @"original value";
NSString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];
NSLog(@"Address :%p value :%@", str, str);
NSLog(@"Address :%p value :%@", copyStr, copyStr);
NSLog(@"Address :%p value :%@", mutableCopyStr, mutableCopyStr);
//string copy Pointer copy mutableCopyStr New address deep copy
}
- (void)testMutableCopy{
NSMutableString *str = [NSMutableString stringWithString:@"original value"];
NSMutableString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];
NSLog(@"Address :%p value :%@", str, str);
NSLog(@"Address :%p value :%@", copyStr, copyStr);
NSLog(@"Address :%p value :%@", mutableCopyStr, mutableCopyStr);
NSMutableString Copy New address mutableCopy new address
}
Copy the code
3. Copy a user-defined object. For a copy of an object, rewrite mutableCopyWithZone: CopyWithZone: Both copy and mutableCopy generate a new object, which is a deep copy. Properties in an object, properties that follow a mutable type either copy or mutableCopy will generate a new object, a deep copy; An attribute of a non-mutable type. When copied, no new object is generated. It is a pointer copy, that is, a shallow copy. MutableCopy creates a new object, which is a copy of the content, or a deep copy.
4. A copy of the array, a deeper copy.
3. Common locks? The lock used by atomic
Locking is a synchronization mechanism used to restrict access to resources and protect data security in multi-threaded environments. Each thread acquires a lock before accessing data or resources and releases the lock when the access is complete. If it is occupied while acquiring the lock, the thread that acquired the lock will wait or loop until the lock is available again.
Classification of locks: Spin locks are more efficient than mutex, but consume more performance than mutex.
1. Spin lock: If the shared data is locked by another thread, the thread will keep trying to access it in an infinite loop. Once the accessed resource is unlocked, the thread waiting for the resource will execute immediately.
Mutex: classified into recursive locks and non-recursive locks.
If the shared data has been locked by another thread, the thread will go to sleep and wait for the lock. Once the accessed resource is unlocked, the thread waiting for the resource will be woken up.
Spin lock, atomic OSSpinLock Dispatch_semaphore_t pthread_rwlock
Mutually exclusive pthread_mutex_t@synchronized NSLock NSConditionLock NSCondition NSRecursiveLock OS_UNfair_lock
The concept of locks, read-write locks, is a special spin lock that can be read by multiple threads, but only one thread is allowed to write.
Conditional lock: a type of mutex that hibernates, or locks, when some resource requirement is not met. When the resource is allocated, the conditional lock is opened and the process continues running. Recursive lock: A type of mutex in which the same thread can add the same lock more than once without blocking. Nonrecursive lock: A type of mutex.
@synchronized
clang -rewrite-objc /Users/main.m
- Dispatch_semaphore_t Semaphore <0 blocks, tasks >=0 pass. Dispatch_semaphore_wait semaphore -1 dispatch_semaphore_signal semaphore +1 Spin lock pthread_rwlock Read/write lock is also a spin lock
dispatch_semaphore_t lock = dispatch_semaphore_create(1);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(lock);
}
end = CACurrentMediaTime();
TimeCosts[LockTypedispatch_semaphore] += end - begin;
printf("Dispatch_semaphore: % 8.2 f ms \ n", (end - begin) * 1000);
}
Copy the code
(pthread_mutex_t) (NSCondition NSRecursiveLock) (@synchronized NSRecursiveLock) (NSLock non-recursive lock) Encapsulated pthread_mutex_t The mutex
pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
end = CACurrentMediaTime();
TimeCosts[LockTypepthread_mutex] += end - begin;
pthread_mutex_destroy(&lock);
printf("The pthread_mutex: % 8.2 f ms \ n", (end - begin) * 1000);
}
NSCondition *lock = [NSCondition new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
TimeCosts[LockTypeNSCondition] += end - begin;
printf("NSCondition: % 8.2 f ms \ n", (end - begin) * 1000);
}
NSLock *lock = [NSLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
TimeCosts[LockTypeNSLock] += end - begin;
printf("NSLock: % 8.2 f ms \ n", (end - begin) * 1000);
{
NSRecursiveLock *lock = [NSRecursiveLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
TimeCosts[LockTypeNSRecursiveLock] += end - begin;
printf("NSRecursiveLock: % 8.2 f ms \ n", (end - begin) * 1000);
}
{
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
TimeCosts[LockTypeNSConditionLock] += end - begin;
printf("NSConditionLock: % 8.2 f ms \ n", (end - begin) * 1000);
}
{
NSObject *lock = [NSObject new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
@synchronized(lock) {}
}
end = CACurrentMediaTime();
TimeCosts[LockTypesynchronized] += end - begin;
printf("@ synchronized: % 8.2 f ms \ n", (end - begin) * 1000);
}
Copy the code