美文网首页
分享面试题

分享面试题

作者: 牛奶红茶 | 来源:发表于2021-02-22 16:15 被阅读0次

1.isa指针是什么?主要用途是用来做什么的?

  -> Objective-C是一门面向对象的编程语言,每一个对象都是一个类的实例。在Objective-C语言的内部,每一个对象都有一个名为isa的指针,指向该对象的类,每一个类描述了一些列它的实例的特点,包括成员变量的列表,成员函数的列表等,每一个对象都可以接受消息,而对象能够接收的消息列表是保存在其对应的类中!在Objective-C语言中,每一个类实际上也是一个对象,每个类也有一个个名为isa的指针,每一个类也可以接受消息,例如[NSObject alloc]就是向NSObject这个类发送名为alloc消息(因为类也是一个对象,那么它必须是另一个类的实例,这个类就是元类,元类也是一个对象,为了设计上的完整,所有的元类的isa指针都会指向一个根元类,根元类本身的isa指针指向自己,这样就形成了一个闭环)

继承关系图

     从图中可以看出

    ->1.NSObject的类中定义了实例方法,例如-(id)init方法 和-(void)dealloc方法

   ->2.NSObject的元类中定义了类方法,例如 +(id)alloc 方法 和 + (void)load 、+ (void)initialize 方法

   ->3.NSObject的元类继承自NSObject类,所以 NSObject 类是所有类的根,因此 NSObject 中定义的      实例方法可以被所有对象调用,例如 - (id)init 方法 和 - (void)dealloc 方法

   ->4.NSObject 的元类的 isa 指向自己

2.assign与weak修饰符有什么区别?

-> weak和assign是一种“非拥有关系”的指针,通过这两种修饰符的指针变量,都不会改变被引用对象的引用计数,但是在一个对象被释放后,weak会自动将指针指向nil,而assign则不会,(在IOS中,向nil发送消息是不会导致崩溃的,所以assign就会导致野指针的错误unrecognized selector sent to instance)

 ->>weak是怎么做到自动置nil?

     runtime对注册的类进行布局,对于weak修饰的对象会放到一个hash表中,用weak指向的对象内存地址最为key,当此对象的引用计数为0的时候会dealloc,假如weak指向的对象内存地址是a,那么就会以a为键,在这个weak表中搜索,找到所有以a为键的weak对象,从而置为nil

3.'#import'跟'#include'有什么区别,@class呢?#import<>跟#import又有什么区别?

->#import是导入头文件的关键字,头文件不会重复导入,而#include是c/c++导入头文件的关键字,头文件会出现重复导入的情况

--------------c/c++头文件如何防止重复导入---------------------

为了避免同一个头文件被#include多次,c/c++中有两种宏实现方式,一种是#ifndef#define方式,另外一种是#pragma once方式,在能够支持这两种方式的编译器上,二者并没有太大的区别(有一些细微的区别)

1)#ifndef

  #ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。

  当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。

  由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。

(2)#pragma once

  #pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。

你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

  其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。

  对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

  另外,这种方式不支持跨平台!

-----------------------------------------------------------------

-> @class是告诉编译器某个类的声明,只有在代码执行时才会检查该类的实现文件,因此使用@class可以解决头文件的互相包含

->#import<>是用来导入系统的头文件,而#import是用来导入用户的头文件

4.为什么要使用多线程,在哪些地方使用过多线程?

->耗时操作(诸如访问远程资源,处理复杂的数据等)

5.有没有遇到过离屏渲染(Offscreen Render)?怎么解决的?

->如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的frame buffer,作为像素数据存储区域,而这也是GPU存储渲染结果的地方。如果有时因为面临一些限制,无法把渲染结果直接写入frame buffer,而是先暂存在另外的内存区域,之后再写入frame buffer,那么这个过程被称之为离屏渲染

->哪些情况会触发离屏渲染?(

->1.对layer使用了mask(遮罩),

->2.对layer使用了masksToBounds,clipsToBounds,

->3.对layer添加了投影,

->4.绘制了文字的layer,

->5.设置了不为1的透明度,因为透明度不为1,像素点颜色的混合运算,需要等这几个不同透明度的图层都渲染好了,提交到  Screen Buffer再进行运行,然后在提交frame buffer进行显示

->6.采用了光栅化layer.shouldRasterize)

6.简述ios事件处理机制?

->移步 https://www.jianshu.com/p/e6639d75bcc6

7.一个不固定UITableViewCell高度的UITableview有哪些性能上需要考虑?

->UITableViewCell重用

->没有用到的的代理方法不要实现

->根据cell的数据提前计算好cell高度

->刷新的时候刷新特定的cell

->尽量少使用clearColor,alpha为0的

8.NSTimer的使用过程中需要注意什么?如何避免?

->移步  https://www.jianshu.com/p/c50c8c4b6ce8

9.请写出不同场景下的方法调用顺序:viewDidDisappear viewDidLoad loadView viewWillDisappear viewDidAppear viewWillAppear

只有一个FirstViewController,页面展示的时候 从FirstViewController push到SecondViewController 从SecondViewController pop回FirstViewController

从SecondViewController popToRootViewController

10.简述IOS应用程序状态?

-->移步 https://www.jianshu.com/p/6dd09c27911c

11.哪里使用过位操作符?

12.为什么分类中不能添加属性?

-> 分类时可以声明属性的,但是不会生成成员变量和实现setter,getter方法,所以要用运行时机制来实现这个属性的getter,setter方法,分类不是一个类,它不能添加成员变量,它只是通过运行时来动态向类里添加方法和属性,综上所述,分类中是可以为一个类添加属性的,但是一定做不到添加成员变量,在分类里使用@propetry声明属性,只是将该属性添加到该类的属性列表,并声明了setter和getter方法,但是没有生成相应 的成员变量,也没有实现setter和getter方法,所以说分类不能添加属性。但是在分类里使用了@property声明属性后,又实现了setter和getter方法,那么在这个类以外可以正常通过点语法给该属性赋值和取值。就是说,在分类里使用@property声明属性,又实现了setter和getter方法后,可以认为给这个类添加上了属性

13.NSString *testString = @“test123456”;

  NSString* test1 =  [testString substringFromIndex:2];

  NSString* test2 =  [testString substringToIndex:2];

  NSString* test3 =  [testString substringWithRange:NSMakeRange(2, 6)]; 

Test1, test2 ,test3的结果分别是多少?

各个值的情况

14.@property 是一种编译器特性,编译期间,编译器都做了哪些工作?如果你很了解的话,   @synthesize/@dynamic 又分别做了哪些工作?

各种属性相关说明

@property 的本质是,@property = ivar + getter + setter;

实例变量+get方法+set方法,也就是说使用@property 系统会自动生成setter和getter方法

-> @synthesize 编译器自动生成getter和setter方法,当开发人员自定义setter和getter方法时,自定义的会屏蔽自动生成的方法

-> @dynamic 告诉编译器不自定生成getter和setter方法,避免变异期间产生警告,但是如果开发人员自己未实现getter和setter方法,程序会崩溃

15.使用一个类的属性时常常使用点语法(OC种点语法也是一种编译特性),点语法实际做了哪些操作?

->点语法进行了方法替换(根据情况替换成getter和setter方法)

->[]方括号的方法调用也是一种变异特性

16.使用过那些开发工具以提高工作效率 ?

17.快速排序:12 5 30 6 8 31 42 21 56 ,一趟快速排序结束后,排序是多少?

18.C 语言中,数组需要指定类型。为什么 OC 种数组不需要,这两个数组有什么区别吗?为什么分为可变与不可变之分?

  ->OC 中数组只能是类指针,因此类型是固定的,OC中数组不能包含基本类型

  -> 添加以及删除操作需要额外开辟空间,增加消耗。

19. load 方法、initialize 方法调用时机,有什么需要注意的?

->移步 https://www.jianshu.com/p/3f21e307b35e

20. 简述delegate和notification的区别,你一般在什么场景下分别使用他们 ?

21.weak 和 strong的区别,一般delegate和block用哪一个,为什么。

22. 一般利用运行时进行哪些操作 ?

23.Objective-C的类可以多重继承吗?可以实现多个接口吗?Category是什么?重写一个类的方法是用继承好还是分类好?为什么

->Object-C不可以多继承,可以实现多个接口,即:可以实现多个Protocol,Category是Object-c类中的分类,通过分类可以为Object-c的类添加扩展方法,一般情况下采用分类的方式比较好,因为category可以在不破坏原有类的代码结构的情况下,为该类扩展方法,并且仅仅对该Category有效,不会影响其他类与元有类的关系

------------------------------------------END-------------------------------------------------------

相关文章

网友评论

      本文标题:分享面试题

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