美文网首页
iOS知识点总结<四>

iOS知识点总结<四>

作者: 陪你看日出去 | 来源:发表于2016-07-05 21:37 被阅读14次

    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并不会立即报错是程序崩溃,而是依次执行下列步骤:
    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: 两个方法即可。发流程如图所示:
    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<argCount ; i++) {  
         }  
         return signature;  
    }  
    
    - (void)forwardInvocation:(NSInvocation *)anInvocation  
    {  
          SEL seletor = [anInvocation selector];  
          if ([someObj respondsToSelector:seletor]) {  
                 [anInvocation invokeWithTarget:someObj];  
          }  
      
    }  
    
    两种消息转发方式的比较
    (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 <objc/runtime.h>  
    
    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知识点总结<四>

          本文链接:https://www.haomeiwen.com/subject/rczhjttx.html