美文网首页
iOS(OC)常见面试题

iOS(OC)常见面试题

作者: LZM轮回 | 来源:发表于2016-06-08 09:13 被阅读143次

    1.iOS怎么管理内存?
    在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上)。如果一个对象创建并使用后没有得到及时释放那么就会占用大量内存。OjbC中的内存管理就需要由开发人员手动维护。1)引用计数器:在ObjC中每个对象内部都有一个与之对应的整数(retainCount),叫“引用计数器”,当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器自动在原来的基础上加1(ObjC中调用一个对象的方法就是给这个对象发送一个消息),当调用这个对象的release方法之后它的引用计数器减1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。2)属性参数:可以通过@property定义属性,此刻不必手动实现getter,setter方法程序仍然没有内存泄露,因为属性定义的时候我们同样加上了参数

    3)自动释放池:一种内存自动释放的机制叫做“自动引用计数”(或“自动释放池”),使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。这样对象就起到了延迟自动释放的效果.注意:######1.autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中;######2.自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁);######3.由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存(对象比较多或者对象占用资源比较多),最好不要放到自动释放池或者考虑放到多个自动释放池;######4.ObjC中类库中的静态方法一般都不需要手动释放,内部已经调用了autorelease方法;
    2.浅复制和深复制的区别
    浅复制:本质是将一个对象1的地址,交给了另一个对象2,如果对象被释放,则对象2所指的地址是不安全的.深复制:要使用copy方法,则对象必须遵守NSCopying协议实质:将原对象的内容复制到一块新的内存空间,拷贝的是整个对象.
    3.类别和类扩展的区别?
    1)类扩展仅能够在原始类中声明(.h或.m中均可,在.m中声明的类扩展其定义的属性和方法均是私有的)2)类扩展的实现仅能够在原始类的.m中编写3)在类扩展中可以扩展类的属性.而在分类中仅能够扩展实例方法和类方法
    4.使用block和使用delegate完成委托模式有什么优点?
    1)使用block实现委托模式优点

    回调的block代码块定义在委托对象函数内部,使代码更为紧凑;适配对象不再需要实现具体某个protocol,代码更为简洁。代码可读性更强,更有连贯性,block经常可以用于completion handler、error handler等。网络请求回调。
    2)delegate的优势:

    1.非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。 2.如果delegate中的一个方法没有实现那么就会出现编译警告/错误 3.协议必须在controller的作用域范围内定义 4.在一个应用中的控制流程是可跟踪的并且是可识别的; 5.在一个控制器中可以定义多个不同的协议,每个协议有不同的delegate 6.没有第三方对象要求保持/监视通信过程。 7.能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller
    5.#import和#include的区别 @class?
    @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import而#import比起#include的好处就是不会引起交叉编译
    6.在一个对象的方法里面:self.name = "object";和name = "object"有什么不同吗?
    self.name ="object":会调用对象的setName()方法;name = "object":会直接把object赋值给当前对象的name属性。
    7.请简要说明viewDidLoad和viewDidUnload何时调用
    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 。
    8.数组和指针的区别
    (1)数组可以申请在栈区和数据区;指针可以指向任意类型的内存块(2)sizeof作用于数组时,得到的是数组所占的内存大小;作用于指针时,得到的都是4个字节的大小(3)数组名表示数组首地址,值不可以改变,如不可以将++作用于数组名上;普通指针的值可以改变,如可将++作用于指针上(4)用字符串初始化字符数组是将字符串的内容拷贝到字符数组中;用字符串初始化字符指针是将字符串的首地址赋给指针,也就是指针指向了该数组
    9.static的作用
    (1)函数体内static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值; (2)在模块内的static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; (3)在模块内的static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内; (4)在类中的static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; (5)在类中的static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。
    10.简述内存分区情况
    (1)代码区:存放函数二进制代码(2)数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量(3)堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放(4)栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数
    11.const char p; charconstp; charconst p; const char const p;四个修饰指针有什么区别
    (1)定义了一个指向不可变的字符串的字符指针(2)和(1)一样(3)定义了一个指向字符串的指针,该指针值不可改变,即不可改变指向 (4)定义了一个指向不可变的字符串的字符指针,且该指针也不可改变指向
    12.MVC的理解?
    MVC模式考虑三种对象:模型对象、视图对象和控制器对象。
    模型对象负责应用程序的数据和定义操作数据的逻辑;
    视图对象知道如何显示应用程序的模型数据;
    控制器对象是M与V之间的协调者。
    13.obj-c的优缺点
    objc优点: 1) Cateogies 2) Posing 3) 动态识别 4) 指标计算 5)弹性讯息传递 6) 不是一个过度复杂的 C 衍生语言 7) Objective-C 与 C++ 可混合编程 缺点: 1) 不支援命名空间 2) 不支持运算符重载 3) 不支持多重继承 4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优 化方法都用不到。(如内联函数等),性能低劣。
    14.队列和栈有什么区别:
    队列和栈是两种不同的数据容器。从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。队列是一种先进先出的数据结构,它在两端进行操作,一端进行入队列操作,一端进行出列队操作。栈是一种先进后出的数据结构,它只能在栈顶进行操作,入栈和出栈都在栈顶操作。
    15.简述视图控件器的生命周期。
    loadView尽管不直接调用该方法,如多手动创建自己的视图,那么应该覆盖这个方法并将它们赋值给试图控制器的view属性。viewDidLoad只有在视图控制器将其视图载入到内存之后才调用该方法,这是执行任何其他初始化操作的入口。viewDidUnload当试图控制器从内存释放自己的方法的时候调用,用于清楚那些可能已经在试图控制器中创建的对象。viewVillAppear当试图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成顶级视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时确保调用[super viewWillAppear:].viewDidAppear当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用[super viewDidAppear:]。
    16.UIView与CLayer有什么区别?

    1. UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性。2) UIView有个重要属性layer,可以返回它的主CALayer实例。3) UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示。即CALayer层是可以嵌套的。4) UIView的layer树形在系统内部,被维护着三份copy。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。5) 动画的运作:对UIView的subLayer(非主Layer)属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是0.5秒。6) 坐标系统:CALayer的坐标系统比UIView多了一个anchorPoint属性,使用CGPoint结构表示,值域是0~1,是个比例值。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5,0.5},即在layer的中央。7)渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay方法来重绘显示。8)变换:要在一个层中添加一个3D或仿射变换,可以分别设置层的transform或affineTransform属性。9)变形:Quartz Core的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。CATransform3D的一套方法提供了一些魔术般的变换效果。
      17.线程与进程的区别和联系?
      进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
      18.ios平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?
      iOS中可以有四种持久化数据的方式:属性列表、对象归档、SQLite3和Core Data;coredata可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。coredata提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用coredata的时候,你不用安装额外的数据库系统,因为core data使用内置的sqlite数据库。core data将你app的模型层放入到一组定义在内存中的数据对象。coredata会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当coredata在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。mac os x中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与coredata框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。CoreData在使用的过程种自己创建这个数据库。Core Data支持对一、对多的关系。
      19.tableView的重用机制?
      UITableView通过重用单元格来达到节省内存的目的:通过为每个单元格指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,以及当单元格滚出屏幕时,允许恢复单元格以便重用.对于不同种类的单元格使用不同的ID,对于简单的表格,一个标识符就够了.
      20.用变量a给出下面的定义
      a)一个整型

    b)一个指向整型数的指针

    c)一个指向指针的的指针,它指向的指针是指向一个整型数

    d)一个有10个整型数的数组

    e)一个有10个指针的数组,该指针是指向一个整型数的

    f)一个指向有10个整型数数组的指针

    g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数

    h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数

    a) int a; b) int *a; c) int a;d) int a[10]e) int a[10];f) int (a)[10];g) int (a)(int);i) int (a[10])(int);

    相关文章

      网友评论

          本文标题:iOS(OC)常见面试题

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