【iOSSharing #7】2019-05-05

797 阅读3分钟

iOS Sharing 系列

目录

1. id、self、super 它们从语法上有什么区别?

2. block 修改捕获变量除了用 __block 还可以怎么做?有哪些局限性?

3. 什么情况使用 weak 关键字,相比 assign 有什么不同?

4. weak属性需要在dealloc中置nil么?

5. ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?

1. id、self、super 它们从语法上有什么区别?

  • id 可作为方法的返回值类型、参数类型,以及变量的类型
  • self 可以用来调用方法,在实例方法中代表当前类的实例,在类方法中代表当前类,多态的一个对象, 它只能作为参数传递,不能作为类型使用,另外它也是消息发送过程中第一个默认参数
  • super 为编译器的一个关键字,告知编译器在调用方法时从父类的方法表中寻找

2. block 修改捕获变量除了用 __block 还可以怎么做?有哪些局限性?

  • 将变量声明为全局的或利用static修饰
  • 也可以把变量声明为类的成员变量或者属性,访问同样不需要 __block

__block 修饰的局部变量会随着 block 销毁而销毁,内存管理与 block 同步,全局/局部静态/全局静态,存在于程序的整个生命周期,成员变量的生命周期由其类控制

3. 什么情况使用 weak 关键字,相比 assign 有什么不同?

(1)、什么情况下使用weak:

  • 在ARC中修饰代理
  • 使用@IBOutlet连接控件
  • 当block会造成循环引用

(2)、与assign的不同

assign可以用于非对象类型,而weak必须用于对象类型


进阶

区别

  • 修饰变量类型的区别
    weak 只可以修饰对象。如果修饰基本数据类型,编译器会报错-“Property with ‘weak’ attribute must be of object type”。 assign 可修饰对象,和基本数据类型。当需要修饰对象类型时,MRC时代使用unsafe_unretained。当然,unsafe_unretained也可能产生野指针,所以它名字是"unsafe_”。

  • 是否产生野指针的区别
    weak 不会产生野指针问题。因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。 assign 如果修饰对象,会产生野指针问题;如果修饰基本数据类型则是安全的。修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。

相似

都可以修饰对象类型,但是assign修饰对象会存在问题。

总结

assign 适用于基本数据类型如int,float,struct等值类型,不适用于引用类型。因为值类型会被放入栈中,遵循先进后出原则,由系统负责管理栈内存。而引用类型会被放入堆中,需要我们自己手动管理内存或通过ARC管理。

weak 适用于delegate和block等引用类型,不会导致野指针问题,也不会循环引用,比较安全。

4. weak属性需要在dealloc中置nil么?

在ARC中,无论是strong修饰的对象还是weak修饰的对象,都不再需要在dealloc中将对象置为nil,编译器会自动帮我们处理,即使编译器不帮助我们处理,在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。

5. ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?

  • 原子性 -- atomic
  • 读写权限 -- readwrite
  • 内存管理 -- 基础数据类型(assign),对象(strong)