面试题

今天看到有人分享了一些面试题,发现自己好多都说不出来,再过几个月就要开始找工作了。趁此机会总结一下吧。

类别(category)与类扩展

类别的作用:在不修改原来类的基础上,为一个类扩展方法(一般是系统的类),如果与本类中的方法重名 会覆盖本类中方法(因为类别中不能使用super))。不建议在类别中添加成员变量,不过 仍然可以利用 runtime 实现setter 和 getter 方法 进行添加。

@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end

//实现文件
#import "ClassName + CategoryName.h"
#import 

static void *strKey = &strKey;
@implementation ClassName (CategoryName)

-(void)setStr:(NSString *)str
{
    objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}

-(NSString *)str
{
    return objc_getAssociatedObject(self, &strKey);
}

@end

类扩展:是category的一个特例 也可以叫做匿名分类。它的作用是为一个类添加一些私有的成员变量和方法。类扩展可以定义在.m文件中,也可以定义在.h文件中。

assgin

直接赋值,引用计数不变 ,一般用在 声明基础数据类型的成员变量

copy

深拷贝 声明NSString 用在不希望声明的NSString 不跟随赋值的字符串变化时, 用copy 拷贝的是内容 不是指针。

retain

浅拷贝 拷贝的是指针 不是内容 (会随着赋值字符串的改变而改变)

strong

强引用 持有对象 引用计数加一 当所用引用它的对象都释放,才会释放。

weak

弱引用 无法持有对象 在创建完 就会被释放 因为没有任何强指针引用它
有IBOutlet修饰的对象上多引入一个强指针

atomic / nonatomic

atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
nonatomic:只是简单的返回这个值。

线程

在iOS中有三种创建线程的方法(http://www.jianshu.com/p/0b0d9b1f1f19#)
(1)NSThread 轻量级 是经过苹果封装后的 一些属性调用起来很方便 但是生命周期还需要我们手动管理

  // 创建
  NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
  // 启动
  [thread start];

或者

  [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];

常见方法

//取消线程
- (void)cancel;

//启动线程
- (void)start;

//判断某个线程的状态的属性
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isCancelled) BOOL cancelled;

//设置和获取线程名字
-(void)setName:(NSString *)n;
-(NSString *)name;

//获取当前线程信息
+ (NSThread *)currentThread;

//获取主线程信息
+ (NSThread *)mainThread;

//使当前线程暂停一段时间,或者暂停到某个时刻
+ (void)sleepForTimeInterval:(NSTimeInterval)time;
+ (void)sleepUntilDate:(NSDate *)date;

(2)GCD
合理利用CPU内核 自动管理线程的生命周期(创建线程、调度任务、销毁线程)
任务与队列
任务:有两种执行方式
>同步执行(sync):会阻塞当前线程 等待block中的任务执行完 然后才会继续执行
>
异步执行(async):不会阻塞当前线程,当前线程会直接往下执行
队列:用于存放任务
放到队列里面的任务,GCD都会FIFO(先进先出)的取出来,不同的是
>串行队列:取出之后放到一个线程中执行
>
并行队列:分别放到不同的线程中

GCD会根据系统资源控制并行的数量,所以任务很多的时候 并不会让所有任务同时执行。

(3)NSOPeration
是对GCD的封装
NSOperation:对应GCD的任务
NSOperationQueue:对应GCD的队列
NSOperation不能封装任务 但他的子类 NSInvocationOperation和NSBlockOperation可以
NSInvocationOperation

  //1.创建NSInvocationOperation对象
  NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
  //2.开始执行
  [operation start]; 

NSBlockOperation

  //1.创建NSBlockOperation对象
  NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
      NSLog(@"%@", [NSThread currentThread]);
  }];

  //2.开始任务
  [operation start];

并发执行:他会在主线程和其他多个线程执行

      //1.创建NSBlockOperation对象
      NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
          NSLog(@"%@", [NSThread currentThread]);
      }];

      //添加多个Block
      for (NSInteger i = 0; i < 5; i++) {
          [operation addExecutionBlock:^{
              NSLog(@"第%ld次:%@", i, [NSThread currentThread]);
          }];
      }

      //2.开始任务
      [operation start];

懒加载 :用到的时候再去加载(getter)

你可能感兴趣的:(面试题)