2018iOS面试题收集

题目

  1. 如何令⾃己所写的对象具有拷贝功能?
  2. 说说你理解weak属性?
  3. Swift mutating关键字的使⽤?
  4. UIView和 CALayer是什什么关系?
  5. 下⾯面的代码输出什么?
  6. @synthesize 和 @dynamic 分别有什么作⽤?
  7. 动态绑定
  8. Category(类别)、 Extension(扩展)和继承的区别
  9. 为什么代理要用weak?代理的delegate和dataSource有什么区别?block和代理的区别?
  10. id和NSObject*的区别
  11. 使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引⽤循环问题?
  12. 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
  13. UIView和CALayer是什么关系?
  14. static有什么作用?
  15. main()之前的过程有哪些?
  16. KVO基本原理?
  17. Swift下的如何使⽤KVC?
  18. Swift有哪些模式匹配?
  19. objc在向⼀一个对象发送消息时,发⽣了什么?
  20. 静态库的原理理是什么?你有没有⾃己写过静态编译库,遇到了了哪些问题?
  21. runloop是来做什么的?runloop和线程有什么关系?主线程默认开启了runloop 么?⼦线程呢?
  22. 不⼿动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放? (比如在⼀一个vc的viewDidLoad中创建)
  23. OC完整的消息转发机制+代码实现
  24. 以+ scheduledTimerWithTimeInterval...的⽅式触发的timer,在滑动⻚面上的列表时,timer会暂定回调,为什么?如何解决?
  25. 如何⼿动触发⼀个value的KVO
  26. 如何对定位和分析项⽬中影响性能的地方?以及如何进⾏性能优化?
  27. 串行并行,异步同步的区别?
  28. 线程是什么?进程是什么?⼆者有什么区别和联系?
  29. RunLoop是什么?
  30. 设有⼀个字符串aabcad,请写⼀段程序,去掉字符串中不相邻的重复字符,即上述字符串处理之后的输出结果为:aabcd
  31. @autoclosure(⾃自动闭包)
  32. iOS app启动如何优化?
  33. swift⾯试题
  34. 怎样防止反编译?
  35. UITableView性能优化,超实用
  36. 不要阻塞主线程
  37. 谈谈你对多线程开发的理解?ios中有几种实现多线程的方法?
  38. 进程和线程的区别?同步异步的区别?并行和并发的区别?
  39. ViewController生命周期
  40. iOS 中的多线程
  41. 内存管理的⼏条原则是什么?按照默认法则,那些关键字生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露露?
  42. dispatch_barrier_async的作用是什么?
  43. 如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
  44. http与https的区别?
  45. 服务器能否知道APNS推送后有没有到达客户端的⽅法?
  46. 什么方式可以看到上架App的头文件?
  47. 阅读过哪些框架的源码?能说说它的架构方式吗
  48. iOS IAP内购审核可能失败的问题
  49. IAP内购中虚拟货币导致审核⽆法通过的问题?

答案

  1. 如何令⾃己所写的对象具有拷贝功能?
    如果想让⾃己的类具备copy⽅法,并返回不可变类型,必须遵循nscopying协议,并且实现
    - (id)copyWithZone:(NSZone *)zone 。如果让⾃己的类具备mutableCopy方法,并且返回可变类型,必须遵守 NSMutableCopying,并实现- (id)mutableCopyWithZone:(nullable NSZone *)zone。 注意:再此说的copy对应不可变类型和mutableCopy对应可变类型⽅法,都是遵从系统规则⽽已。如果你想实现⾃己的规则,也是可以的。

  2. 说说你理解weak属性?
    释放时,调⽤clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个 entry从weak表中删除,最后清理对象的记录。

追问的问题⼀: 实现weak后,为什么对象释放后会自动为nil?
runtime对注册的类, 会进行布局,对于weak对象会放入一个hash表中。 ⽤weak指向的对象内存地址作为key,当此对象的引⽤用计数为0的时候会dealloc,假如weak指向的对象内存地址是a,那么就会以a为键, 在这个weak表中搜索,找到所有以a为键的weak对象,从而设置为nil?。

追问的问题⼆: 当weak引⽤指向的对象被释放时,⼜是如何去处理weak指针的呢?
1、调⽤用objc_release
2、因为对象的引⽤用计数为0,所以执行dealloc
3、在dealloc中,调⽤用了_objc_rootDealloc函数
4、在_objc_rootDealloc中,调⽤了object_dispose函数
5、调用objc_destructInstance
6、最后调用objc_clear_deallocating,详细过程如下:
a. 从weak表中获取废弃对象的地址为键值的记录
b. 将包含在记录中的所有附有 weak修饰符变量的地址,赋值为nil
c. 将weak表中该记录删除
d. 从引⽤计数表中删除废弃对象的地址为键值的记录

  1. Swift mutating关键字的使用?
    在Swift中,包含三种类型(type): struct,enum,class
    其中struct和enum是值类型(value type),class是引⽤用类型(reference type)
    但是与Objective-C不同的是,struct和enum也可以拥有方法(method), 其中⽅法可以为实例方法(instance method),也可以为类⽅法(type method),实例方法是和类型的一个实例绑定的。
    在swift官方教程中有这样⼀句话:
    “Structures and enumerations are value types. By default, the properties of a value type cannot be modified from within its instance methods.”
    ⼤致意思就是说,虽然结构体和枚举可以定义⾃己的⽅方法,但是默认情况下,实例方法中是不可以修改值类型的属性。
//// 1. 在结构体的实例例⽅方法⾥里里⾯面修改属性
struct Persion {
    var name = ""
    mutating func modify(name: String) {
        self.name = name
     }
}
/// 2. 在协议⾥里里⾯面, 如何继承的结构体或枚举类型,想要改遍属性值, 必须添加 mutating
protocol Persionprotocol {
    var name : String { get }
    mutating func modify(name: String)
}
struct Persion : Persionprotocol {
    var name = ""
    mutating func modify(name: String) {
        self.name = name
     }
}
/// 3. 在枚举中直接修改self属性
 enum Switch {
    case On, Off
    mutating func operatorTion() {
         switch self {
            case .On:
            self = .Off default:
            self = .On 
         }
    } 
}
var a = Switch.On a.operatorTion()
print(a)
  1. UIView和 CALayer是什么关系?

UIView 显示在屏幕上归功于 CALayer,通过调⽤ drawRect ⽅法来渲染⾃身的内容, 调节 CALayer 属性可以调整 UIView 的外观,UIView 继承⾃UIResponder,⽐起 CALayer 可以响用户事件,Xcode6 之后可以⽅便的通过视图调试功能查看图层之间的关系。

UIView 是 iOS 系统中界⾯元素的基础,所有的界面元素都继承自它。它内部是由 Core Animation 来实现的,它真正的绘图部分,是由⼀个叫 CALayer(Core Animation Layer)的类来管理理。UIView 本身,更像是⼀个 CALayer 的管理器,访问它的跟绘图和坐标有关的属性,如 frame,bounds 等,实际上内部都是访问它所在 CALayer 的 相关属性。UIView 有个 layer 属性,可以返回它的主 CALayer 实例,UIView 有一个layerClass方法,返回主 layer所使用的类,UIView 的子类,可以通过重载这个方法,来让 UIView 使⽤不同的 CALayer 来显示,如:

- (Class) layerClass {
      // 使某个 UIView的⼦子类使⽤用 GL来进⾏行行绘制
    return ([CAEAGLLayer class]);
 }

UIView 的 CALayer 类似 UIView 的⼦子 View 树形结构,也可以向它的 layer 上添加⼦ layer,来完成某些特殊的显示。例例如下⾯的代码会在⽬标 View 上敷上⼀层黑⾊的透明薄膜。

grayCover = [[CALayer alloc]init]; 
grayCover.backgroudColor = [[UIColor blackColor]colorWithAlphaComponent:0.2].CGColor; 
[self.layer addSubLayer:grayCover];

补充部分:这部分有深度了了,⼤致了解⼀下吧,UIView 的 layer 树形在系统内部被系统维护着三份 copy
1.逻辑树,就是代码里可以操纵的,例如更改 layer 的属性等等就在这⼀份
2.动画树,这是⼀个中间层,系统正是在这⼀层上更改属性,进⾏各种渲染操作。
3.显示树,这棵树的内容是当前正被显示在屏幕上的内容。
这三棵树的逻辑结构都是一样的,区别只有各自的属性。

答案很详细有点多,不写了。想要的朋友可以加群,然后群文件下载。群号:801216530。

你可能感兴趣的:(2018iOS面试题收集)