ios笔试题一份(1)

1.写一个NSString类的实现 
+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;

+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding{
 NSString *obj;
 obj = [self allocWithZone: NSDefaultMallocZone()];
 obj = [obj initWIthCString: nullTerminatedCString encoding: 
encoding];
 return AUTORELEASE(obj);
}

2.写一个委托的interface
答:  
@protocol MyDelegate; 
@interface MyClass: NSObject 

 id <MyDelegate> delegate; 

// 委托方法 
@protocol MyDelegate 
- (void)didJobs:(NSArray *)args; 
@end

3.请写出你对MVC模式的理解 
答:MVC模式考虑三种对象:模型对象、视图对象和控制器对象。
模型对象负责应用程序的数据和定义操作数据的逻辑;
视图对象知道如何显示应用程序的模型数据;
控制器对象是M与V之间的协调者。

4.什么是键-值,键路径是什么 
答:模型的性质是通过一个简单的键(通常是个字符串)来指定的。
视图和控制器通过键来查找相应的属性值。在一个给定的实体中,
同一个属性的所有值具有相同的数据类型。键-值编码技术用于进行
这样的查找—它是一种间接访问对象属性的机制。 
键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接
在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来
每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型实现的
方式指定相关对象的性质。通过键路径,您可以指定对象图中的一个任意
深度的路径,使其指向相关对象的特定属性。

5.请列举你熟悉cocoa touch框架(至少三个)
答:
Core Animation 
通过 Core Animation,您就可以通过一个基于组合独立图层的简单的编程
模型来创建丰富的用户体验。 
Core Audio 
Core Audio 是播放,处理和录制音频的专业技术,能够轻松为您的应用
程序添加强大的音频功能。 
Core Data 
提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理
任何应用或大或小的数据模型。 
功能列表:框架分类 
下面是 Cocoa Touch 中一小部分可用的框架: 
音频和视频 
Core Audio 
OpenAL 
Media Library 
AV Foundation 
数据管理 
Core Data 
SQLite 
图形和动画 
Core Animation 
OpenGL ES 
Quartz 2D 
网络> 
Bonjour 
WebKit 
BSD Sockets 
用户应用 
Address Book 
Core Location 
Map Kit 
Store Kit
6.自动释放池是什么,如何工作
当您向一个对象发送一个autorelease 消息时,Cocoa就会将该对象
的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此
自动释放池定义的作用域内的其它对象可以向它发送消息。当 程序
执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对
象也就被释放。 
ojc-c 是 通过一种"referring counting"(引用计数)的方式来管理内
存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰
到有copy,retain的时候引用计数都会加一, 每当碰到release和
autorelease的时候引
用计数就会减一,如果此对象的计数变为了0, 
就会被系统销毁. 
2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西
一般不用你管的. 
3. autorelease和release没什么区别,只是引用计数减一的时机不
同而已,autorelease会在对象的使用真正结束的时候才做引用计数
减一. 
 
7.readwrite,readonly,assign,retain,copy,nonatomic
属性的作用 
@property是一个属性访问声明,扩号内支持以下几个属性: 
1,getter=getterName,setter=setterName,设置setter与getter的方法名 
2,readwrite,readonly,设置可供访问级别 
2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类
型与环循引用问题 
3,retain,setter方法对参数进行release旧值再retain新值,所有实现
都是这个顺序(CC上有相关资料) 
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值
release,再Copy出新的对象,retainCount为1。这是为了减少对上下文
的依赖而引入的机制。 
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。
注意,如果不加此属性,
则默认是两个访问方法都为原子型事务访问。锁
被加到所属对象实例级。

8.ViewController 的 loadView, viewDidLoad, viewDidUnload 
分别是在什么时候调用的?在自定义ViewController的时候这几个
函数里面应该做什么工作?
viewDidLoad在view 从nib文件初始化时调用,loadView在controller的view为nil时调用。
此方法在编程实现view时调用,view 控制器默认会注册memory warning notification,
当view controller的任何view 没有用的时候,viewDidUnload会被调用,在这里实现将
retain 的view release,如果是retain
的IBOutlet view 属性则不要在这里release,
IBOutlet会负责release 。 
 
9.类工厂方法是什么
 类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中, 返回
被创建的对象,并
进行自动释放处理。这些方法的形式是+ (type)className...
(其中 className不包括任何前缀)。
工厂方法可能不 仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以 为
初始化过程提供对
象的分配信息。
类工厂方法的 另一个目的是使类(比如NSWorkspace)提供单件实例。虽 然init...方法
可以确认一
个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实
例,然后还必须释放该实例。
工厂 方法则可以避免为可能没有用的对象盲目分配内存。
 
 
10.为什么很多内置类如UITableViewController的delegate属性都是assign而不是
retain的?
答:会引起循环引用。
这里delegate我们只是想得到实现了它delegate方法的对象,然后拿到这个对象的指针就
可以了,
我们不期望去改变它或者做别的什么操作,所以我们只要用assign拿到它的指针就可以了。
而 用retain的话,计数器加1。我们有可能在别的地方期望释放掉delegate这个对象,
然后通过一些判断比如说它是否已经被释放,做一些操作。但是 实际上它retainCount还
是1,没有被释放掉,要在UITableViewController的dealloc里面才被释放掉(这里我只是
举个 例子,一般retain的对象都是在dealloc里被释放)。这里就会造成一些问题出现。
而如果你确定不会有冲突的问题出现的话,或者你也希望用到delegate的这个对象,直到
你不用它为止,那么用retain也未尝不可,只是需要最后release一次。   
  

浅复制和深复制的区别?//浅拷贝和深拷贝
答案:
浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身。//通过对象的指针来访问这个对象
深层复制(mutableCopy):复制引用对象本身
意思就是有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源
还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了
两份独立对象本身。//当修改A时,A copy不变。

打个比喻:1、浅拷贝就是:你挂了,你妈妈喊你回家吃饭时找不到人了,她很伤心。2、深拷贝就是:你克隆了一个你自己:你挂了、你兄弟还在,你妈妈喊你回家吃饭时能找到人。所以、孩子,安全起见、深拷贝吧,记得内存管理就是了。


类别的作用?继承和类别在实现中有何区别?
答案:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。// category:类、种类
并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。//类别跟类的优先级
类别主要有3个作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。
(3)向对象添加非正式协议。
 继承可以增加,修改或者删除方法,并且可以增加属性。
//非正式协议:是使用类别category来实现,非正式协议是NSObject的一个类别,这样任何类的对象都可以作为委托对象来使用,它可以列出对象能够执行的所有方法,这样用来实现委托, 我们可以使用选择器来判断该非正式协议中是否有这个方法。
正式协议:是一个命名的方法列表,与非正式协议相比不同的是,它要求显示的采用协议,采用协议的方法是在类的@interface声明中列出协议的名称,此时,实现协议的类应该遵守协议,承诺实现协议中的所有方法。

3 类别和类扩展的区别。
 答案:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。
extensions可以认为是一个私有的Category。
4. oc中的协议和java中的接口概念有何不同?
答案:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。
informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。
其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里
“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。
这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。
这么看,总觉得类别这玩意儿有点像协议的可选协议。"
现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,
现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。
5.什么是KVO 和 KVC?
答 案:kvc:键 - 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。//KVC运用了一个isa- swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa 指针,就是is a kind of的意思,指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

 

kvo(Key-Value Observing):键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。
用过的一个地方是对于按钮点击变化状态的的监控。
比 如我自定义的一个button。   //当属性改变时KVO回提供自动的消息通知。每次属性改变了就会发送消息通知。这是因为当这个方案已经被明确定义,获得框架级支持,可以方便的采用,开 法人员不需要设计自己的观察这模型,可以直接在工程里使用。KOV的架构可以支持多个观察者观察同一个属性,以及相关值。


[cpp] 
[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:
“当 通过KVC调用对象时,比如:[self valueForKey:@”someKey”]时,程序会自动试图通过几种不同的方式解析这个调用。首先查找对象是否带有 someKey 这个方法,如果没找到,会继续查找对象是否带有someKey这个实例变量(iVar),如果还没有找到,程序会继续试图调用 -(id) valueForUndefinedKey:这个方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUndefinedKeyException 异常错误。
 
(cocoachina.com注:Key-Value Coding查找方法的时候,不仅仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者_someKey以及 _getsomeKey这几种形式。同时,查找实例变量的时候也会不仅仅查找someKey这个变量,也会查找_someKey这个变量是否存在。)
 
设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象能够在错误发生前,有最后的机会响应这个请求。这样做有很多好处,下面的两个例子说明了这样做的好处。“
来至cocoa,这个说法应该挺有道理。
因为我们知道button却是存在一个highlighted实例变量.因此为何上面我们只是add一个相关的keypath就行了,
可以按照kvc查找的逻辑理解,就说的过去了。
6.代理的作用?
答案:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。

7.oc中可修改和不可以修改类型。
答案:就是可动态添加修改和不可动态添加修改一样。
比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。
8.我们说的oc是动态运行时语言是什么意思?
答案:多态。 主要是将数据类型的确定由编译时,推迟到了运行时。
这个问题其实浅涉及到两个概念,运行时和多态。
运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。
//都用有一个相同的方法,不同的对象以自己的方式响应了相同的消息.
因此也可以说,运行时机制是多态的基础
9.通知和协议的不同之处?
答案:协议有控制链(has-a)的关系,通知没有。//通知:它可以一对多,一条消息可以发送给多个消息接受者,但是不会处理消息
控制链:单一拥有和可控制的对应关系。
10.关于多态性
答案:多态,子类指针可以赋值给父类。
对象不仅仅可以已本身的类型存在,也可以作为其父类类型存在。 多态性是允许将父对象设置成为和一个或多个它的子对象相等的技术, 多态性使得能够利用同一类(基类)类型的指针来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作.


11.说说响应链
答案: 事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。
12. frame和bounds有什么不同?
答案:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)//frame:框架、结构
bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)//bounds:界限
14. NSOperation队列
操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。
网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。
这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,
但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。
但是转念一想其实可以参考银行的取票和叫号系统。
因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。
但是后来看到一票关于这操作队列话题的文章,其中有一句提到
“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”
瞬间觉得这个queue名字有点忽悠人了,还不如pool~
综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。
15.是否在一个视图控制器中嵌入两个tableview控制器?
答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,
只能说可以嵌入一个tableview视图。而是宏观的表示视图控制者,那我们倒是可以把其看成一个视图控制者,它可以控制多个视图控制器,比如TabbarController

16. 一个tableView是否可以关联两个不同的数据源?你会怎么处理?
答案:首先从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。
 
    
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   if(indexPath.section == 0)
   {
   }
   if(indexPath.section == 1)
   {
   }
}
17. 什么是id类型
id类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。
例如:id number
将number声明为id类型的变量。可声明的方法使其具有id类型的返回值,如下:
-(id)newObject;(int)type;
这个程序声明了一个名为newObject的实例方法,它具有名为type的单个整型参数并有id类型的返回值。应该注意的是,对返回值和参数类型声明来说,id是默认的类型。
id类型是objetive-c中非常中药店额数据类型,它是多态和动态绑定的基础。

#include,#import,@class的区别

#include

        #include  <>    :用于对 系统文件的引用,编译器会在系统文件目录下去查找该文件。
 
        #include "xx.h":用于对用户自定义的文件的引用,编译器首先会去用户目录下查找,然后去安装目录,最后去系统目录查找。
 
       注:使用include要注意重复引用的问题:
 
       class A,class B都引用了class C,class D若引用class A与class B,就会报重复引用的错误。
 
#import
      功能与include基本相同,不过它避免了重复引用的问题。所以在OC中我们基本用的都是import。
 
@class
      @class就是告诉编译器有这个类存在,但是类是如何实现的不用告诉编译器.若.m文件用到了这个类,还是要在.m文件汇总import这个类的。
      既然这样,为什么不直接在头文件中import呢,举个例子:
      class A引用了class B,class B引用了class C.... , class A,B,C...的头文件又import了很多文件,那么 import了A的话,编译器就需要编译大量的文件,编译时间就会增加。 
 
      难道头文件中都是用@class吗?当然不是,有时也是需要#import的,那么什么时候该用什么呢?
(1)一般如果有继承关系的用#import,如B是A的子类那么在B中声明A时用#import;
 
(2) 另外就是如果有循环依赖关系,如:A->B,B->A这样相互依赖时,如果在两个文件的头文件中用#import分别声明对方,那么就会出现头文件循环利用的错误,这时在头文件中用@class声明就不会出错;
 
(3)还有就是自定义代理的时候,如果在头文件中想声明代理的话如@interface SecondViewController:UIViewController时应用#import不然的话会出错误,注意XXXXDelegate是自定义的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值