前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS面试题梳理(二)

iOS面试题梳理(二)

作者头像
Jacklin
发布2018-05-15 17:13:24
1.2K0
发布2018-05-15 17:13:24
举报
文章被收录于专栏:攻城狮的动态攻城狮的动态

继续.....

循环引用的产生原因,以及解决方法

1.产生原因:如下图所示,对象A和对象B相互引用了对方作为自己的成员变量,只有自己销毁的时候才能将成员变量的引用计数减1。对象A的销毁依赖于对象B的销毁,同时对象B销毁也依赖与对象A的销毁,从而形成循环引用,此时,即使外界没有任何指针访问它,它也无法释放。

2.多个对象间依然会存在循环引用问题,形成一个环,在编程中,形成的环越大越不容易察觉,如下图所示:

解决方法:

1,事先知道存在循环引用的地方,在合理的位置主动断开一个引用,是对象回收;

2.使用弱引用的方法。

KeyPath、KVC、KVO

键路径(KeyPath):

1.在一个给定的实体中,同一个属性的所有值具有相同的数据类型。

2.键-值编码技术用于进行这样的查找,它是一种间接访问对象属性的机制。 键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。

3.键路径使您可以以独立于模型实现的方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性

键值编码(KVC):

1.键值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制,非对象类型的变量将被自动封装或者解封成对象,很多情况下会简化程序代码;

2.KVC的缺点:一旦使用 KVC 你的编译器无法检查出错误,即不会对设置的键、键路径进行错误检查,且执行效率要低于合成存取器方法和自定的 setter 和 getter 方法。因为使用 KVC 键值编码,它必须先解析字符串,然后在设置或者访问对象的实例变量。

键值观察(KVO):

1.键值观察机制是一种能使得对象获取到其他对象属性变化的通知 ,极大的简化了代码。

2.实现 KVO 键值观察模式,被观察的对象必须使用 KVC 键值编码来修改它的实例变量,这样才能被观察者观察到。

Demo

比如我自定义的一个button

代码语言:javascript
复制
[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil]; #pragma mark KVO 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
     if ([keyPath isEqualToString:@"highlighted"] ) { 
      [self setNeedsDisplay]; } 
  }

对于系统是根据keypath去取的到相应的值发生改变,理论上来说是和kvc机制的道理是一样的。

KVC机制通过key找到value的原理

1.当通过KVC调用对象时,比如:[self valueForKey:@”someKey”]时,程序会自动试图通过下面几种不同的方式解析这个调用;

2.首先查找对象是否带有 someKey 这个方法,如果没找到,会继续查找对象是否带有someKey这个实例变量(iVar),如果还没有找到,程序会继续试图调用 -(id) valueForUndefinedKey:这个方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUndefinedKeyException异常错误。

3.补充:KVC查找方法的时候,不仅仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者_someKey以_getsomeKey这几种形式。同时,查找实例变量的时候也会不仅仅查找someKey这个变量,也会查找_someKey这个变量是否存在。

4.设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象能够在错误发生前,有最后的机会响应这个请求。

Objective-C 中如何实现 KVO

1.注册观察者(注意:观察者和被观察者不会被保留也不会被释放)

代码语言:javascript
复制
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath 
options:(NSKeyValueObservingOptions)options 
context:(void *)context;

2.接收变更通知

代码语言:javascript
复制
- (void)observeValueForKeyPath:(NSString *)keyPath 
ofObject:(id)object change:(NSDictionary *)change   context:(void *)context;

3.移除对象的观察者身份

代码语言:javascript
复制
- (void)removeObserver:(NSObject *)observer 
forKeyPath:(NSString *)keyPath;

3.KVO中谁要监听谁注册,然后对响应进行处理,使得观察者与被观察者完全解耦。KVO只检测类中的属性,并且属性名都是通过NSString来查找,编译器不会检错和补全,全部取决于自己。

代理的作用(Delegate)

1.代理又叫委托,是一种设计模式,代理是对象与对象之间的通信交互,代理解除了对象之间的耦合性。

2.改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。

3.另外一点,代理可以理解为java中的回调监听机制的一种类似。

4.代理的属性常是assign的原因:防止循环引用,以至对象无法得到正确的释放。

NSNotification、Block、Delegate和KVO的区别

1.代理是一种回调机制,且是一对一的关系,通知是一对多的关系,一个对向所有的观察者提供变更通知;

2.效率:Delegate比NSNOtification高;

3.Delegate和Block一般是一对一的通信;

4.Delegate需要定义协议方法,代理对象实现协议方法,并且需要建立代理关系才可以实现通信;

5.Block:更加简洁,不需要定义繁琐的协议方法,但通信事件比较多的话,建议使用Delegate;

Objective-C中可修改和不可以修改类型

1.可修改不可修改的集合类,就是可动态添加修改和不可动态添加修改。

2.比如NSArrayNSMutableArray,前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间.

当我们调用一个静态方法时,需要对对象进行 release 吗?

不需要,静态方法(类方法)创建一个对象时,对象已被放入自动释放池。在自动释放池被释放时,很有可能被销毁。

当我们释放我们的对象时,为什么需要调用[super dealloc]方法,它的位置又是如何的呢?

因为子类的某些实例是继承自父类的,因此需要调用[super dealloc]方法, 来释放父类拥有的实例,其实也就是子类本身的。一般来说我们优先释放子类拥 有的实例,最后释放父类所拥有的实例。

谓词的认识

Cocoa 中提供了一个NSPredicate的类,该类主要用于指定过滤器的条件, 每一个对象通过谓词进行筛选,判断条件是否匹配。如果需要了解使用方法,请看谓词的具体使用.

static、self、super关键字的作用

1.函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值.

2.在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问.

3.在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明.

4.在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝.

5.self:当前消息的接收者。

6.super:向父类发送消息。

#include与#import的区别、#import 与@class 的区别

  1. #include#import其效果相同,都是查询类中定义的行为(方法);
  2. #import不会引起交叉编译,确保头文件只会被导入一次;
  3. @class 的表明,只定 义了类的名称,而具体类的行为是未知的,一般用于.h 文件;
  4. @class#import 编译效率更高。
  5. 此外@class#import 的主要区别在于解决引用死锁的问题。

@public、@protected、@private 它们的含义与作用

  1. @public:对象的实例变量的作用域在任意地方都可以被访问 ;
  2. @protected:对象的实例变量作用域在本类和子类都可以被访问 ;
  3. @private:实例变量的作用域只能在本类(自身)中访问 .

解释 id 类型

任意类型对象,程序运行时才决定对象的类型。

switch 语句 if 语句区别与联系

均表示条件的判断,switch语句表达式只能处理的是整型、字符型和枚举类型,而选择流程语句则没有这样的限制。但switch语句比选择流程控制语句效率更高。

isMemberOfClass 和 isKindOfClass 联系与区别

1.联系:两者都能检测一个对象是否是某个类的成员

2.区别:isKindOfClass 不仅用来确定一个对象是否是一个类的成员,也可以用来确定一个对象是否派生自该类的类的成员 ,而isMemberOfClass 只能做到第一点。

3.举例:如 ClassA派 生 自NSObject 类 , ClassA *a = [ClassA alloc] init];,[a isKindOfClass:[NSObject class]] 可以检查出 a 是否是 NSObject派生类 的成员,但 isMemberOfClass 做不到。

iOS 开发中数据持久性有哪几种?

数据存储的核心都是写文件。

1.属性列表:只有NSString、NSArray、NSDictionary、NSData可writeToFile;存储依旧是plist文件。plist文件可以存储的7中数据类型:array、dictionary、string、bool、data、date、number。

2.对象序列化(对象归档):对象序列化通过序列化的形式,键值关系存储到本地,转化成二进制流。通过runtime实现自动化归档/解档,请参考这个文章。实现NSCoding协议必须实现的两个方法:

3.编码(对象序列化):把不能直接存储到plist文件中得到数据,转化为二进制数据,NSData,可以存储到本地;

4.解码(对象反序列化):把二进制数据转化为本来的类型。

5.SQLite 数据库:大量有规律的数据使用数据库。

6.CoreData :通过管理对象进行增、删、查、改操作的。它不是一个数据库,不仅可以使用SQLite数据库来保持数据,也可以使用其他的方式来存储数据。如:XML。

7.CoreData的介绍:

  • CoreData是面向对象的API,CoreData是iOS中非常重要的一项技术,几乎在所有编写的程序中,CoreData都作为数据存储的基础。
  • CoreData是苹果官方提供的一套框架,用来解决与对象声明周期管理、对象关系管理和持久化等方面相关的问题。
  • 大多数情况下,我们引用CoreData作为持久化数据的解决方案,并利用它作为持久化数据映射为内存对象。提供的是对象-关系映射功能,也就是说,CoreData可以将Objective-C对象转换成数据,保存到SQL中,然后将保存后的数据还原成OC对象。

8.CoreData的特征:

1.通过CoreData管理应用程序的数据模型,可以极大程度减少需要编写的代码数量。

2.将对象数据存储在SQLite数据库已获得性能优化。

3.提供NSFetchResultsController类用于管理表视图的数据,即将Core Data的持久化存储在表视图中,并对这些数据进行管理:增删查改。

4.管理undo/redo操纵;

5.检查托管对象的属性值是否正确。

Core Data的6成员对象

1.NSManageObject:被管理的数据记录Managed Object Model是描述应用程序的数据模型,这个模型包含实体(Entity)、特性(Property)、读取请求(Fetch Request)等。

2.NSManageObjectContext:管理对象上下文,持久性存储模型对象,参与数据对象进行各种操作的全过程,并监测数据对象的变化,以提供对undo/redo的支持及更新绑定到数据的UI。

3.NSPersistentStoreCoordinator:连接数据库的Persistent Store Coordinator相当于数据文件管理器,处理底层的对数据文件的读取和写入,一般我们与这个没有交集。

4.NSManagedObjectModel:被管理的数据模型、数据结构。

5.NSFetchRequest:数据请求;

6.NSEntityDescription:表格实体结构,还需知道.xcdatamodel文件编译后为.momd或者.mom文件。

Core Data的功能

1.对于KVC和KVO完整且自动化的支持,除了为属性整合KVO和KVC访问方法外,还整合了适当的集合访问方法来处理多值关系;

2.自动验证属性(property)值;

3.支持跟踪修改和撤销操作;

4.关系维护,Core Data管理数据的关系传播,包括维护对象间的一致性;

5.在内存上和界面上分组、过滤、组织数据;

6.自动支持对象存储在外部数据仓库的功能;

7.创建复杂请求:无需动手写SQL语句,在获取请求(fetch request)中关联NSPredicate。NSPreadicate支持基本功能、相关子查询和其他高级的SQL特性。它支持正确的Unicode编码、区域感知查询、排序和正则表达式;

8.延迟操作:Core Data使用懒加载(lazy loading)方式减少内存负载,还支持部分实体化延迟加载和复制对象的数据共享机制;

9.合并策略:Core Data内置版本跟踪和乐观锁(optimistic locking)来支持多用户写入冲突的解决,其中,乐观锁就是对数据冲突进行检测,若冲突就返回冲突的信息;

10.数据迁移:Core Data的Schema Migration工具可以简化应对数据库结构变化的任务,在某些情况允许你执行高效率的数据库原地迁移工作;

11.可选择针对程序Controller层的集成,来支持UI的显示同步Core Data在IPhone OS之上,提供NSFetchedResultsController对象来做相关工作,在Mac OS X上我们用Cocoa提供的绑定(Binding)机制来完成的。

对象可以被copy的条件

12.只有实现了NSCopyingNSMutableCopying协议的类的对象才能被拷贝,分为不可变拷贝和可变拷贝,具体区别戳这;

NSCopying协议方法

代码语言:javascript
复制
- (id)copyWithZone:(NSZone *)zone {
 MyObject *copy = [[[self class] allocWithZone: zone] init]; copy.username = [self.username copyWithZone:zone]; return copy;
}

自动释放池工作原理

1.自动释放池是NSAutorelease类的一个实例,当向一个对象发送autorelease消息时,该对象会自动入池,待池销毁时,将会向池中所有对象发送一条release消息,释放对象。

2.[pool release]、 [pool drain]表示的是池本身不会销毁,而是池子中的临时对象都被发送release,从而将对象销毁。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 攻城狮的动态 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 循环引用的产生原因,以及解决方法
  • KeyPath、KVC、KVO
    • 键路径(KeyPath):
      • 键值编码(KVC):
        • 键值观察(KVO):
          • Demo
            • KVC机制通过key找到value的原理
            • 在 Objective-C 中如何实现 KVO
            • 代理的作用(Delegate)
            • NSNotification、Block、Delegate和KVO的区别
            • Objective-C中可修改和不可以修改类型
            • 当我们调用一个静态方法时,需要对对象进行 release 吗?
            • 当我们释放我们的对象时,为什么需要调用[super dealloc]方法,它的位置又是如何的呢?
            • 谓词的认识
            • static、self、super关键字的作用
            • #include与#import的区别、#import 与@class 的区别
            • @public、@protected、@private 它们的含义与作用
            • 解释 id 类型
            • switch 语句 if 语句区别与联系
            • isMemberOfClass 和 isKindOfClass 联系与区别
            • iOS 开发中数据持久性有哪几种?
            • Core Data的6成员对象
            • Core Data的功能
            • 对象可以被copy的条件
            • 自动释放池工作原理
            相关产品与服务
            数据保险箱
            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档