美文网首页面试
iOS之面试题笔记2

iOS之面试题笔记2

作者: 请输入账号名 | 来源:发表于2016-11-16 23:54 被阅读85次

    注:以下的内容是我自己面试遇到的或者是在网上找到的,然后自己总结了下,不恰当的地方请指正,万分感激!!

    1.如果设计一个秒表的APP

    为了防止手指在触摸屏幕的时候停止跳动,一般会用到哪个类?
    一般会用到 NSRunLoop类?????

    2.如果需要持久化对象,需要实现的协议是:

    实现的协议是NSCoding的协议。// 归档和结归档。

    NSCoding Delegate Method
    - (void)encodeWithCoder:(NSCoder *)aCoder {
      // 进行编码操作
      [aCoder encodeObject:_instance forKey:@"_intance.key"];
    }
    
    - (void)initWithCoder:(NSCoder *)aDecoder {
      // 进行解码操作
      if (self = [super init]) {
        self.instance = [aDecoder decodeObjectForKey:@"_instance.key"];
      }
      return self;
    }
    

    3.UIApplication类帮助我们运行Maps,sms,浏览器或其他程序的时候用的方法是:- (BOOL)openURL:(NSURL*)url;

    openURL:方法,/*'URL'就是统一资源定位符。*/
    UIApplication类有个功能十分强大的openURL:方法
    - (BOOL)openURL:(NSURL*)url;
    openURL:方法的部分功能有
    // 打电话:
    UIApplication *app = [UIApplication sharedApplication];
    [app openURL:[NSURL URLWithString:@"tel://10086"]];
    //发短信 :
    [app openURL:[NSURL URLWithString:@"sms://10086"]];
    // 发邮件 :
    [app openURL:[NSURL URLWithString:@"mailto://12345@qq.com"]];
    // 打开一个网页资源:
    [app openURL:[NSURL URLWithString:@"http://ios.cn"]];
    打开其他app程序:openURL方法,可以打开其他APP。
    

    4.在viewController中,init loadView viewWillAppear等的执行顺序。

    执行的顺序为:
    ->init方法:执行关键数据初始化操作,注意这里不要做view相关操作
    ->loadView->viewDidLoad->viewWillAppear->viewWillLayoutSubviews->viewDidLayoutSubviews->viewDidAppear->viewWillDisappear->viewDidDisappear->viewWillUnload->viewDidUnload。

    5.performSelector:withObject:方法的作用是什么?

    简而言之就是程序在运行的时候去找方法,而不在编译的时候找方法。如果写了一个方法却不存在,直接调用执行这个方法,会在编译的时候报错,而如果使用performSelector进行调用的话,不会再编译的时候报错,而是在程序运行的时候进行报错而导致崩溃。

    5.Socket和HTTP的区别 (TCP/IP)

    http://blog.csdn.net/zeng622peng/article/details/5546384

    a.HTTP:

    HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
    由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

    b.Socket

    c.区别

    很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

    注:

    TCP/IP的三从握手:
    HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
    手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
    建立起一个TCP连接需要经过“三次握手”:
    第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
    第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
    握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客户端交互,最终确定断开)

    6.polymorphism(多态)

    多态就是多个对象想要你同一个方法的时候有着不同的结果,这就是多态,这都要用到继承的。

    7.为什么很多内置类如UITableViewController的delegate的属性都是用的assign而不是retain。

    首先如果使用了retain的话,会造成循环引用。
    如果控制器的有个对象a持有tableView的对象b,而恰好b的delegate又持有a,而如果delegate的属性是retain的话,那么在a想要释放的时候,a所持有的b是不会被释放,因而a也得不到释放,所以为了避免循环引用,要用assign。

    8.在一个对象的方法里面:self.name = "object";和name = "obeject";有什么不同。

    1.self.name:是会调用name的setName()方法。
    2.name:会直接把object赋值给当前对象的name属性。

    9.如何实现深拷贝

    http://www.cocoachina.com/ios/20141113/10213.html
    首先拷贝分为深拷贝和浅拷贝;
    1.浅拷贝:只复制指向对象的指针,而不复制引用的对象本身,是通过复制对象的指针来访问指针。

    char* str = (char*)malloc(100);
    char* str2 = str;
    

    2.深拷贝:复制的是对象本身。加入A修改了,而A_Copy是不会被修改的。
    默认遵守了NSCopying和NSMutableCopying协议的可以有

    NSString *string = @”dddd";
    NSString *stringCopy = [string copy];
    NSMutableString *stringDCopy = [string mutableCopy];
    [stringMCopy appendString:@"!!"];
    

    以上的代码得知,string和stringCopy的指向的地址是一致的,值也固然是一致的,但是如果更改了string的值,string的地址会改变,而stringCopy的地址和值均不改变。

    但是如果没有遵守这两个协议的,也是可以构造。还是得遵守NSCopying协议和实现copyWithZone:方法。

    #pragma  mark - 协议的遵守
    @interface MyObj : NSObject<NSCopying, NSMutableCopying>{
        NSMutableString *_name;
        NSString * _imutableStr ;
        int _age;
    }     
    @property (nonatomic, retain) NSMutableString *name;
    @property (nonatomic, retain) NSString *imutableStr;
    @property (nonatomic) int age;
    
    #pragma  mark - Copy的构造
    - (id)copyWithZone:(NSZone *)zone{
        MyObj *copy = [[[self class] allocWithZone :zone] init];
        copy->name = [_name copy];
        copy->imutableStr = [_imutableStr copy];
        copy->age = age;
        return copy;
    }
    
    #pragma  mark - MutableCopy的构造
    - (id)mutableCopyWithZone:(NSZone *)zone{
        MyObj *copy = NSCopyObject(self, 0, zone);
        copy->name = [_name mutableCopy];
        copy->age = age;
        return copy;
    }
    

    9.JSON和XML解析的原理

    区别:
    1.XML和JSON的可读性都基本相同,但是XML的可读性比较好。
    2.可扩展性:两者都具有很好的扩展性,
    3.编码难度:JSON的编码比较容易
    4.解码难度:JSON的解码难度基本为0,XML需要考虑到子节点和父节点
    5.数据体积:JSON相对XML而言体积小,传递速度更快
    6.数据交互:JSON和JS的交互更加方便,更好的解析出来,更好的数据交互
    7.数据描述:XML对数据描述性比较好
    JSON解析原理
    遍历字符串中的字符,最终根据格式规定的特殊字符,比如:
    {} [] :等进行区分,
    {}:是一个字典的开始
    []:是一个数组的开始
    ::字典的键 值 的区别
    最终将JSON数据转化为字典,字典中的值可能是数组或者是字符串。
    XML的解析原理
    常用的解析方式是两种:DOM解析和SAX解析
    DOM常用建立树形结构的方式访问XML文档,DOM解析把XML文档转化为包含其内容的树,并且可以对树进行遍历。使用DOM解析的时候,需要处理整个XML文档,所以对性能和内存的要求比较高;
    SAX采用的是事件模型,SAX解析XML文档时可以触发一系列事件,当发现给定的tag值之后,可以激活一个回调方法,告诉该方法制定的tag已经找到,SAX对于内存的要求比较低。

    10.什么是简便构造方法

    - (instancetype)init
    {
        self = [super init];
        if (self) {
            <#statements#>
        }
        return self;
    }
    

    初始化对象(分配空间并且初始化)
    作用:
    用作初始化对象的成员变量.
    把 C 语言指针初始化为 NULL
    把 OC 对象初始化为 nil
    把基本数据类型初始化为0

    11.什么是谓词

    Predicate
    谓词就相当于指定过滤器的条件。创建NSPredicate对象,这个对象可以准确的描述需要的条件,通过谓词筛选每个对象,就可以判断它们是否与条件相匹配
    原理类似于在数据库中进行查询。

    12.在项目中,什么时候使用GCD什么时候使用NSOperation

    GCD一般做异步处理 。NSOperation一般是多个操作,可以方便的控制异步的执行数量,如下载任务。
    两者的区别:
    1.GCD:是APPLE为多核的并行运算提出的解决方案,他会自动利用更多的CPU内核,可以自动管理线层的生命。GCD是纯C语言的API,任务是用块来表示的,而块是个轻量级的数据结构。
    2.NSOperation:他是oc的对象,operation是个重量级的oc对象,而且NSOperation和NSOperationQueue的好处如下:
    a.取消某个操作
    b.指定操作间的依赖关系
    c.通过键值观测机制监控NSOperation对象的属性
    d.指定操作的优先级
    e.重用NSOperation对象。

    13.什么是block,block实现原理。

    1.块也就是我们所说的block,块与函数类似,只不过是直接定义在另一个函数里的,和定义在那个函数共享一个范围内的东西。block是用“^”表示的,后面跟着一对花括号,括号里面的是现实代码。例如:

    ^ {
      // block implementation is here
    }
    

    block其实就是一个值,自己有其相关的类型,也可以像int类型等把block赋值给变量。

    void (^someBlock)() = ^ {
      // block implementation is here
    };
    

    这里的block类型的语法结构如下:

    return_type (^block_name)(parameters)
    

    2.block是可以分配在栈上或堆上的,也可以是全局的,分配在栈上的block是可以通过copy函数copy到堆上的(深拷贝),这样就具备了和oc对象一样的引用计数了。
    3.block的实现原理
    在oc引入块之前,要实现相同的功能的,就需要传入函数的指针或选择子的名称,提供给其他的方法进行调用。
    而block在内存中的结构为isa、flags、reserved、invoke、discriptor。而isa也是指向Class对象的指针;在内存中最为重要的是invoke变量,这个函数指针指向block中的现实代码。而descriptor变量指向的是结构体的指针,其中申明了block对象的总体大小;这里还有两个辅助函数对应的指针,分别是copy和dispose,copy是要保留捕获的对象,而dispose是讲捕获的对象进行释放。
    block是可以拿到所在函数范围内所有东西,所以在block里可以拿到被捕获的变量,但是默认是不能够对变量进行修改的,如需要进行修改是要加上__block修饰符的。

    14.谈谈对响应链的理解

    事件响应链:
    包括了点击事件,画面刷新事件等,在试图栈内从上至下,或从下至上传播,可以说点事件的分发,传递及处理(具体的看Touch事件)
    首先解释下响应者链的概念:
    A.UIResponder类,是UIKit中一个用于处理事件响应的基类。窗口上所有事件触发都有该类响应(即事件处理入口),所有窗口上的View和控制器UIViewController都是其派生类。
    B.调用UIResponder类提供的方法或熟悉,我们就可以捕捉到窗口上的所有响应事件,并且进行处理。
    C.响应者链条是由多个响应者对象连接起来的链条,其中响应者对象是能处理事件的对象,所有的view和VC都是响应对象,利用响应者链条可以让多个控件处理同一个触摸事件。
    事件传递机制:
    如果当前的view不能处理当前事件,那么事件将会沿着响应者链
    (Responder Chain)进行传递,直到遇到能处理该事件的响应者(Responder Object)。
    接收事件的initial view如果不能处理该事件并且自己也不是顶层的View,则事件会往他的父类view进行传递
    initial view的父视图获取事件如果还是不能处理,则会继续往上传递,循环这个过程。如果顶层的view还是不能处理这个事件的话,则事件会传递给她们的控制器VC。
    如果VC也不能处理,则传递给UIWindow,此时UIWindow还是不能处理的话,就传递给UIApplication,如果UIApplication还是不能处理的话,这个事件就会被废弃掉。
    注:事件的分发和以上的过程是相反的。事件分发主要是找到事件能够被处理的对象。

    15.frame和bounds有什么区别

    frame的位置和大小是以本个视图的父视图为基准的。
    bounds的位置和大小是本个试图为基准的。

    16.写一个标准的宏MIN,这个宏输入两个参数,并返回较小的一个

    #define MIN(a,b) ((a)>(b)?(b):(a)) // 三元运算
    

    17.说一说对NSRunLoop的理解。

    Runloop 是什么?Runloop 还是比较顾名思义的一个东西,说白了就是一种循环,只不过它这种循环比较高级。一般的 while 循环会导致 CPU 进入忙等待状态,而 Runloop 则是一种“闲”等待。当没有事件时,Runloop 会进入休眠状态,有事件发生时, Runloop 会去找对应的 Handler 处理事件。Runloop 可以让线程在需要做事的时候忙起来,不需要的话就让线程休眠。
    几乎每个讲 Runloop 的文章都会引用的图,大体说明了 Runloop 的工作模式:

    工作模式

    图中展现了 Runloop 在线程中的作用:从 input source 和 timer source 接受事件,然后在线程中处理事件。

    Runloop 和线程是绑定在一起的。每个线程(包括主线程)都有一个对应的 Runloop 对象。我们并不能自己创建 Runloop 对象,但是可以获取到系统提供的 Runloop 对象。

    主线程的 Runloop 会在应用启动的时候完成启动,其他线程的 Runloop 默认并不会启动,需要我们手动启动。

    18.nil,Nil,NULL,NSNull的区别

    1.nil和 C 语言的 NULL 相同,在 objc/objc.h 中定义。nil 表示 Objective-C 对象的值为空。在 C 语言中,指针的空值用 NULL 表示。在 Objective-C 中, nil 对象调用任何方法表示什么也不执行,也不会崩溃。
    2.Nil:那么对于我们 Objective-C 开发来说,Nil 也就代表((void *)0)。但是它是用于代表空类的. 比如:Class myClass = Nil;
    3.NULL : 在 C 语言中,NULL是无类型的,只是一个宏,它代表空. 这就是在 C/C++中的空指针。对于我们 Objective-C 开发来说, NULL 就表示((void*)0).
    4. NSNull:NSNULL是继承于 NSObject 的类型。它是很特殊的类,它表示是空,什么也不存储,但是它却是对象,只是一个占位对象。使用场景就不一样了,比如说服务端接口中让我们在值为空时,传空。

    NSDictionry *parameters = @{@"arg1" : @"value1",@"arg2" : arg2.isEmpty ? [NSNull null] : arg2};
    

     NULL、 nil、 Nil 这三者对于 Objective-C 中值是一样的,都是(void *)0,那么为什么要区分呢?又与 NSNull 之间有什么区别:
     NULL 是宏,是对于 C 语言指针而使用的,表示空指针;
     nil 是宏,是对于 Objective-C 中的对象而使用的,表示对象为空;
     Nil 是宏,是对于 Objective-C 中的类而使用的,表示类指向空;
     NSNull 是类类型,是用于表示空的占位对象,与 JS 或者服务端的null 类似的含意。

    相关文章

      网友评论

        本文标题:iOS之面试题笔记2

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