1.常见的属性修饰符有哪些?(引用简书 just东东)
MRC :nonatomic atomic assign retain copy readwrite readonly等。
ARC :nonatomic atomic assign strong copy readwrite readonly nonull nullable等。
1.assign 用于基本数据类型修饰符,不更改引用计数,是由栈自动释放。
2.retain 跟strong是一样的,释放旧对象,传入的新对象引用计数+1 在MRC中release成对出现。
3.strong 告诉系统把这个对象保留在堆上,直到没有指针指向。arc来管理引用计数。
4.weak 在强引用之前尽可能的保留,不改变引用计数,weak引用是弱引用,并没有持有它,它本质上是分配一个不被持有的属性,当引用者销毁weak引用的指针会自动被置为nil,可以避免循环引用。
5.copy 一般用来修改不可变类型的属性字段,防止本对象属性受外界影响。 nsstring nsarray nsdictionary.
`
classmentObject * object = [[classmentObject alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"dassd",@"das", nil];
object.array = array;//@property (nonatomic, strong) NSArray *array;
如果这里用copy object.array 不会跟着外部array的变化而变化,不是同一个引用。
[array addObject:@"daas"];
for (int i = 0; i<array.count; i++) {
NSLog(@"-----%@",array[i]);//3个
}
for (int i = 0; i<object.array.count; i++) {
NSLog(@"%@",object.array[i]);//strong 3个 copy2个
}
`
6.readwrite 可以读写,也就是默认生成的getter setter方法。
7.readonly 只读 会告诉编译器不用自动生成setter方法。不可以赋值操作。
8.nonatomic 非原子性访问,可以多线程访问变量,会导致读写线程不安全,但是会提高执行性能。
9.atomic 原子性,对setter getter方法进行加锁保证,但不包括可变属性的操作和访问,给数组添加对象或者一处对象,是不再atomic的负责范围之内的,所以给atomic修饰的数组添加对象或者移除对象是没办法保证线程安全的,原子性访问的缺点就是会小号性能导致执行效率慢。
10.nonull 设置属性或方法参数不能为空,不能用于基本数据类型。
11.nullabel 设置属性或方法参数可以为空。
2.深拷贝和浅拷贝?(blog.csdn.net/weixin_3954…)
深拷贝拷贝的是内容,浅拷贝拷贝的是指针,如果A拷贝B 此时修改B 如果A也改变了就是浅拷贝,如果A没有改变就是深拷贝。如果自己去实现深拷贝,就需要一层层的遍历去拷贝,深拷贝的意义就在于,有可能被多人操作的数据,如果一处修改了会影响其他地方,使用深拷贝,把数据作为自己的,怎么修改都是自己的事情,不会影响到其他人。
1.不可变字符串NSString通过copy对象后,生成的对象与原对象指向同一个地址,属于浅拷贝;通过mutableCopy生成的对象与原对象指向不同的地址,属于深拷贝。
2.可变字符串NSMutableString无论是通过copy还是mutableCopy,生成的对象均指向不同的地址,属于深拷贝。
- (void)testStringCopy {
NSString *str = @"original value";
NSString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];
NSLog(@"地址:%p 值:%@", str, str);
NSLog(@"地址:%p 值:%@", copyStr, copyStr);
NSLog(@"地址:%p 值:%@", mutableCopyStr, mutableCopyStr);
//string copy 指针拷贝 mutableCopyStr 新地址 深拷贝
}
- (void)testMutableCopy{
NSMutableString *str = [NSMutableString stringWithString:@"original value"];
NSMutableString *copyStr = [str copy];
NSMutableString *mutableCopyStr = [str mutableCopy];
NSLog(@"地址:%p 值:%@", str, str);
NSLog(@"地址:%p 值:%@", copyStr, copyStr);
NSLog(@"地址:%p 值:%@", mutableCopyStr, mutableCopyStr);
//NSMutableString copy 新地址 mutableCopy 新地址
}
3.对象的拷贝 自定义对象,针对对象的拷贝,重写mutableCopyWithZone: CopyWithZone: 无论是copy还是mutableCopy都会产生新的对象,均为深拷贝。 对象中的属性,遵循可变类型的属性无论是copy还是mutableCopy都会产生新的对象,均为深拷贝;非可变类型的属性,copy时没有产生新的对象,为指针拷贝,即浅拷贝;mutableCopy时产生新的对象,为内容拷贝,即深拷贝。
4.数组的拷贝,更深一层的拷贝。
3.常见的锁?atomic的使用的锁
锁是一种同步机制,用于多线程环境中对资源访问的限制,保护数据安全。 每一个线程在访问数据或者资源前都会先获取锁,并在访问结束之后释放锁。如果获取锁的时候被占用,则会获取锁的线程会等待或循环访问,直到锁重新可用。
锁的分类:自旋锁效率高于互斥锁,但是比互斥锁耗性能。
1.自旋锁:如果共享的数据被其他线程加锁了,线程会以死循环的方式一直尝试去访问,一旦被访问的资源解锁,则等待资源的线程会立即执行。
2.互斥锁:分为递归锁和非递归锁。
如果共享的数据已经有其他线程加锁了,线程会进入休眠状态等待锁,一旦被访问的资源解锁,则等待资源的线程会被唤醒。
自旋锁,atomic OSSpinLock dispatch_semaphore_t pthread_rwlock
互斥锁 pthread_mutex_t @synchronized NSLock NSConditionLock NSCondition NSRecursiveLock os_unfair_lock
锁的概念分类, 读写锁,是特殊的自旋锁,可以多个线程来读,但是只允许一个线程来写。
条件锁:是互斥锁的一种,当进程的某些资源要求不满足这个条件时就会进入休眠,也就是锁住了,当资源被分配到了,条件锁就打开了,进程继续运行。 递归锁:互斥锁的一种 同一个线程对同一把锁可以加多次,而不会引发阻塞。 非递归锁:互斥锁的一种。
@synchronized
clang -rewrite-objc /Users/main.m
- dispatch_semaphore_t 信号量 信号量<0会阻塞,>=0任务可以顺利通过。dispatch_semaphore_wait信号量-1 dispatch_semaphore_signal信号量+1 自旋锁 pthread_rwlock 读写锁也是自旋锁
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.2f ms\n", (end - begin) * 1000);
}
2.(pthread_mutex_t) ( NSCondition NSConditionLock条件锁) (@synchronized 递归锁 NSRecursiveLock) (NSLock非递归锁)封装的pthread_mutex_t 互斥锁
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("pthread_mutex: %8.2f 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.2f 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.2f 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.2f 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.2f 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.2f ms\n", (end - begin) * 1000);
}