iOS知识点总结<四>

1、请简述什么是主键、什么是外键

主键:

一张表(关系)的一个列(睡醒)或多个列可以作为主键,但是前提是让这个列作为主键,这个列就能保证该列下的各行(元素)的值不能相同,比如说你用姓名属性做主键的话,那么这个主键就不一定可以,如果有两个人是同样的名字的话,就不嗯那个做到该属性下的各个元祖数据的值不同,如果用阿拉伯数字做主键就是一个很好的选择。

外键:

一张表(关系)的列(属性)他同时保存在表1和表2中,他不是表1的主键,而是表2的主键,就可以书他是表1的外键。

那什么时候选键呢:能唯一标识(关系)中行(元组)的列(属性),则成该属性为候选键,也成候选关键字或候选码;由此来看候选键可以不只一个。

2、请简述你理解的内存管理。

创建对象并使用后需要释放,否则会出现内存泄露,内存管理跟非手动内存管理MRC和自动内存管理ARC。
(1)在手动内存管理机制下,如果使用alloc,copy(MutabelCopy),retain一个对象时,在使用完毕需要向该对象发送release,或者autorelease消息来释放这个对象,其他方法创建的对象不需要管理内存。
(2)在自动内存管理机制下,系统维护的自动释放池会自动处理。

3、如何实现流媒体格式的视频播放,边缓边存?

(1)需要在视频播放器和服务器之间添加一层类似代理的机制,视频播放器不再直接访问服务器,而是访问代理对象,代理对象去访问服务器获得数据,之后返回给视频播放器,同时代理对象根据一定的策略缓存数据。
(2)AVURLAsset中的resourceLoader可以实现这个机制,resourceLoader的delegate就是上述的代理对象。
(3)视频播放器在开始播放之前首先检测是本地cache中是否有此视频,如果没有才通过代理获得数据,如果有,则直接播放本地cache中的视频即可。

4、请简述weak和assgin有什么区别?

assign这是指针赋值,不对引用计数操作,使用之后,如果没有设置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针。
在ARC模式下编程时,指针变量一定要用weak修饰,只有基本数据类型和结构体需要用assgin,例如delegate,一定要用weak修饰

Objective-C数据类型可以分为:

基本数据类型、对象类型和id类型。
(1)基本数据类型有:int、float、double和char类型。
(2)对象类型就是类或协议所声明的指针类型,例如:NSAutoreleasePool * pool,其中NSAutoreleasePool是一个类,NSAutoreleasePool *是它指针类型。
(3)id类型可以表示任何类型,一般只是表示对象类型,不表示基本数据类型。

5、如何实现ARC和MRC的混合编程?

<1> 尝试使用Xcode的转换工具(失败率比较高)
<2> 在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译
备注:
   (1) 演示中使用的RegexKitLite还需要导入libicucore.dylib动态库
   (2) 如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可
<3> 将MRC的第三方库直接编译成静态库使用
注意:在编译静态库时,不能添加动态库引用
说明:RegexKitLite是对NSString添加的正则表达式分类
在项目中,如果使用的静态库中包含分类,则需要在Other Link Flag中添加 -ObjC选项
Xcode 项目中我们可以使用 ARC 和MRC的混合模式。
(1)如果你的项目使用的MRC模式,则为 ARC 模式的代码文件加入 -fobjc-arc 标签。
(2)如果你的项目使用的是 ARC 模式,则为MRC 模式的代码文件加入 -fno-objc-arc 标签。
 添加标签的方法:
    打开:你的target -> Build Phases -> Compile Sources.
    双击对应的 *.m 文件
    在弹出窗口中输入上面提到的标签 -fobjc-arc / -fno-objc-arc
    点击 done 保存

6、Object-C中是否支持多继承?

Object-C不支持多继承,由于消息机制查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问题。不过我们可以找到如下集中间接实现多继承目的的方法:消息转发机制、delegate和protocol、类别。

一、消息转发:
当向someObject发送某消息,但runtime system在当前类和父类中都找不到对应方法的实现时,runtime system并不会立即报错是程序崩溃,而是依次执行下列步骤:
iOS知识点总结<四>_第1张图片
20130524164518623.jpg
分别简述一下流程:
(1)动态方法解析:向当前类发送resolveInstanceMethod:信号,检查是否动态向该类添加方法。
(2)快速消息转发:检查该类是否实现了 forwardingTargetForSelector: 方法,若实现了则调用这个方法。若该方法返回值对象非nil或非self,则向该返回对象重新发送消息。
(3)标准消息转发:runtime发送methodSignatureForSelector:消息获取Selector对应的方法签名。返回值非空则通过forwardInvocation:转发消息,返回值为空则向当前对象发送doesNotRecognizeSelector:消息,程序崩溃退出。     
 顾名思义,我们可以利用上述过程中的(2)、(3)两种方式来完成消息转发。
快速消息转发
 快速消息转发的实现方法很简单,只需要重写 - (id)forwardingTargetForSelector:(SEL)aSelector  方法即可。
我来举个简单的例子,比如现有2个类:Teacher 和 Doctor,Doctor可以做手术(operate方法)。
 @interface Doctor : NSObject  
 - (void)operate;  
 @end  
通过快速消息转发,可以很轻松的让teacher调用doctor的方法做手术。Teacher类需要实现将消息转发给Doctor:
- (id)forwardingTargetForSelector:(SEL)aSelector  
{  
      Doctor *doctor = [[Doctor alloc]init];  
      if ([doctor respondsToSelector:aSelector]) {  
            return doctor;  
       }  
       return nil;  
}  

#######虽然消息可以动态转发传递,但是编辑器的静态检查是绕不过的,那么问题来了,既然Teacher类没有实现operate方法又该如何声明呢?到目前为止,我只想到下面2种方法:

声明方法1 —— 类别
@interface Teacher (DoctorMethod)  
- (void)operate;  
@end  
声明方法2 ———— 导入头文件、调用时强转类型
Teacher类头文件需要包含Doctor头文件,告诉编译器去Doctor.h中可以找到operator方法的声明,并且在调用时强转类型。
 Teacher *teacher = [[Teacher alloc]init];  
 [(Doctor *)teacher operate];  
标准消息转发
标准消息转发需要重写 methodSignatureForSelector: 和 forwardInvocation: 两个方法即可。发流程如图所示:
iOS知识点总结<四>_第2张图片
20130524165504839.jpg
重写方法:
 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector  
{  
     NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];  
     if (signature==nil) {  
            signature = [someObj methodSignatureForSelector:aSelector];  
     }  
     NSUInteger argCount = [signature numberOfArguments];  
     for (NSInteger i=0 ; i
两种消息转发方式的比较
(1)快速消息转发:简单、快速、但仅能转发给一个对象。     
(2)标准消息转发:稍复杂、较慢、但转发操作实现可控,可以实现多对象转发。
二、delegate和protocol
 委托是Objective-C中最常用的一种回调机制。用法我觉得没什么好说的,总结一下该机制特点:委托协助主体完成操作任务,将需要定制化的操作预留给委托对象来自定义实现,类似子类化主体。除此之外,可以用作事件监听。
三、类别
个人认为类别是Objective-C设计的一大精髓,也是我爱上Objective-C的最大理由。类别是个强大的东西,它既可以为类添加方法,也可以添加实例。一定有不少人不认同,想提醒我:类别的局限性之一就是无法向类中添加新的实例变量。 背书真心毁人,听我举个例子慢慢说。 重新再来个Teacher类:
 @interface Teacher : NSObject  
{  
     NSUInteger age;  
}  
@end  
光有个年龄还不能满足对teacher的描述,我想加个profession实例来存teacher的专业。直观的想法是子类化Teacher,其实也可以用类别。
你需要了解一下 runtime 编程知识,关注一下 objc_setAssociatedObject 和 objc_getAssociatedObject 。
//  
//  Teacher+Profession.m  
//    

#import "Teacher+Profession.h"  
#import   

const char *ProfessionType = "NSString *";  
@implementation Teacher (Profession)  

-(void)setProf:(NSString*)prof  
{  
     objc_setAssociatedObject(self, ProfessionType, prof, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
}  

-(NSString *)prof  
{  
   NSString *pro = objc_getAssociatedObject(self, ProfessionType);  
return pro;  
}  

@end  
现在就可以通过setProf: 和 prof 来存取 teacher 的 profession 值了。

你可能感兴趣的:(iOS知识点总结<四>)