iOS面试汇总题目

150 阅读2分钟

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

  1. 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);
    }

4.KVO KVC

5.事件传递

6.消息转发 三个阶段

7.nstimer

8.block

9.扩展与分类关联对象。