iOS面试前的一些准备(持续更新)

  1. OC动态性:动态类型、动态绑定、动态加载
  2. 内存管理原则:谁创建,谁释放;谁引用,谁管理
  3. 生命属性时,如果使用new开头命名,需要自己定义get方法
  4. 非ARC工程编译ARC工程参数:-fobjc-arc,反之:-fno-fobjc-arc
  5. MVVM架构:把原来Controller中的业务逻辑和页面逻辑剥离出来放到ViewModel层
  6. 协议默认字段:@required
  7. category中的方法拥有更高的优先级,最好不要覆盖父类的方法,因为可能导致消息链断裂;category可用于分散类的实现
  8. 键值编码KVC效率低于存取方法
  9. 键值监听基于KVO,需要使用KVC改变变量的值,才能触发监听(待验证),ValueForUndfinedKey:方法可以在抛出异常前获得机会响应
  10. 代理/委托是一种设计模式,用assign声明是为了防止循环引用
  11. 代理和Block通常是一对一的,NSNotification是一对多的,代理比通知的效率高
  12. 在Dealloc方法中,先释放自己拥有的对象,最后调用[super dealloc];
  13. 函数体内的static变量只会分配一次内存,下次访问时依旧存在,即使在函数体外面访问也是如此
  14. switch语句比if语句效率高
  15. isMemberOfClass:用于检测一个对象是否是一个类的实例,isKindOfClass:检测一个对象是否是一个类或者其子类的实例
  16. 数据持久化方案:1)属性列表 2)对象序列化(NSCoding协议) 3)SQLite数据库 4)CoreData 5)MFDB
  17. 栈区用于存放方法参数,局部变量等信息,向低地址扩展,内存连续;堆区由程序员分配,向高地址扩展,不连续。栈的效率高于堆,因为栈由系统支持,而堆由C/C++库支持
  18. 线程有自己独立的堆栈和局部变量,但是没有单独的地址空间,一个线程死掉整个进程就会死掉,因此多进程程序更健壮,但是其进程切换开销较大
  19. iOS主线程堆栈1M,子线程512K,不可改变,只有主线程可以更改UI
  20. iOS自带的JSON解析类效率最高,但只能用于iOS 5之后
  21. 消息推送:1)苹果APNs服务:无论应用开启与否,都可以发送到手机端,但是可能有延迟 2)第三方推:普遍使用socket机制实现,及时性较好,但是应用关闭后不能发送到手机
  22. NSUserDefaults是系统提供的一种保存少量数据的数据持久化方式,默认存储在Preferences目录下
  23. LayoutSubViews在view的frame改变时调用
  24. frame和bounds的区别:都是一个坐标系统,前者参照点是父坐标系统,后者参照点是本身的坐标系统
  25. view的touch时间:began、moved、ended、cancelled
  26. RunLoop默认只有主线程会启动,因为通常子线程执行一个任务后就会退出并归还资源,如果要持续监听,则需要手动开启RunLoop
  27. UIViewController的完整生命周期:
    -[ViewController initWithNibName:bundle:];
    -[ViewController init];
    -[ViewController loadView];
    -[ViewController viewDidLoad];
    -[ViewController viewWillDisappear:];
    -[ViewController viewWillAppear:];
    -[ViewController viewDidAppear:];
    -[ViewController viewDidDisappear:];
  28. 为了避免设置圆角触发离屏渲染,我们可以写一个UIImage的category,利用Quartz2d绘制圆角
  29. -imageNamed:加载后会在内存中缓存
    -initWithContentsOfFile:加载后不会缓存,每次都会重新加载
    两种方法在不同场合应该选择性的使用,优化内存消耗
  30. -[ViewController initWithCoder:]-[ViewController initWithNibName:Bundle]:首先从归档文件中加载UIViewController对象。即使是纯代码,也会把nil作为参数传给后者。
  31. KVC提供了一种使用字符串去访问对象实例变量的方法,当类实现了相关的访问器方法时,使用点语法和KVC访问都可以,但是没有实现访问器方法时,使用KVC同样可以访问到对象的属性。访问器方法是很好的东西,因此只要有可能,KVC同样会借助访问器方法工作:首先尝试通过访问器方法工作,如果访问器方法不存在,怎尝试直接访问key或者key、isKey、getKey、_setKey,如果仍然没有找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法,我们此时还有最后的机会进行补救操作
  32. KVO实现原理:当某个类的对象第一次被观察时, 系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。 派生类在被重写的 setter 方法实现真正的通知机制 ,就如前面手动实现键值观察那样。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制。当然前提是要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现 KVO 的。同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。此外,派生类还重写了 dealloc 方法来释放资源。在更新后的setter方法中,会新增对
    -(void)willChangeValueForKey:(NSString *)key
    -(void)didChangeValueForKey:(NSString *)key
    两个方法的调用,其中,didChangeValueForKey:方法负责调用:
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context,因此实现了KVO
  33. 使用KVO的三种方法:1)利用KVC,在重写的访问器方法中,会调用will/didChangeValueForKey:方法,没有访问器方法时,会在setValue:forKey方法中调用这两个方法;
    2)直接通过访问器方法触发KVO,因为runtime会重写类;
    3)我们自己显示的调用will/didChangeValueForKey:方法
    总之,只要有will/didChangeValueForKey:方法,我们就可以使用KVO
  34.  KVO机制的优点:1)简化代码;
    不足:1)不能传递一个selector或者block作为回调,虽然可以通过重写addObserver:forKeyPath:options:context:,但是需要解决由此引出的一些列问题。
  35. 静态方法常驻内存,在堆区分配内存,动态方法(实例方法)在堆栈上分配空间。实际上二者都是在代码段分配空间,代码段不可写 
  36. 源对象有可变和不可变两种,复制有copy和mutableCopy两种,copy用于生成一个不可变的对象,mutableCopy用于生成一个可变的对象,如果源对象和副本对象都是不可变的,即对一个不可变的对象进行copy操作,相当于retain操作,属于浅拷贝,其余都是深拷贝
  37. 使用copy或者mutableCopy,需要实现NSCopying协议的-(id)copyWithZone:(NSZone *)zone或者对应的NSMutableCopying协议
  38.  iOS中不同APP实现文件共享的方式:
    1)通过URL Scheme调起其他APP
    2)利用系统接口UIDocumentInteractionController
    3)粘贴板UIPasteboard
  39. APNS工作流程:
    1)APP向APNS注册,获得deviceToken
    2)APP把deviceToken发送给我们自己的推送服务器
    3)我们通过push服务器把要推送的信息推送给APNS
    4)APNS推送消息到device

你可能感兴趣的:(ios修炼之路)