1.Swift 和OC 如何相互调用?
Swift 调用 OC代码
* 需要创建一个 Target-BriBridging-Header.h 的桥文件,在乔文件导入需要调用的OC代码头文件即可
OC 调用 Swift代码
* 直接导入 Target-Swift.h文件即可, Swift如果需要被OC调用,需要使用@objc 对方法或者属性进行修饰
2.类(class) 和 结构体(struct) 有什么区别?
在 Swift 中,class 是引用类型(指针类型), struct 是值类型 String,Array,Dictionary,Set
* 值类型: 比如结构体,枚举,是在栈空间上存储和操作的
引用类型
* 引用类型只会使用引用对象的一个"指向"; 赋值给var、let或者给函数传参,是将内存地址拷贝一份,类似于制作一个文件的替身(快捷方式、链接),指向的是同一个文件。属于浅拷贝(shallow copy)
* 引用类型: 比如 Class,是在堆空间上存储和操作的
类:继承,引用计数的。
结构体,不用考虑引用计数的问题。
3.Swift 中,什么可选型(Optional)
Optional是 OC 中没有的数据类型,是苹果在 Swift 中引入的全新类型,它的特点就是可有值,也可以没有值,当它没有值的时候就是 nil. 并且 Swift 中的nil 和 OC 中 nil 也不一样,在 OC 中只有对象才能为 nil, 而在 Swift 中,当基础类型(整型,浮点,布尔等)没有值的时候,也是 nil, 而不是一个初始值,没有初始值的值是不能使用的,所以就产生了 Optional 类型.定义一个 Optional 的值很容易,只需要在类型后面加上问号(?)就行了
1. 在 Swift 中,可选型是为了表达一个变量为空的情况,当一个变量为空,他的值就是 nil
2. 在类型名称后面加个问号? 来定义一个可选型
3. 值类型或者引用类型都可以是可选型变量
4.、泛型的概念
1. 泛型代码能根据所定义的要求写出可以用于任何类型的灵活的、可复用的函数。可以编写出可复用、意图表达清晰、抽象的代码。
func test<T>(_ a: T, _ b: T)->Bool{
return a == b
}
//经典例子swap,使用泛型,可以满足不同类型参数的调用
func swap<T>(_ a: inout T, _ b: inout T){
let tmp = a
a = b
b = tmp
}
5.访问控制关键字 open, public, internal, fileprivate, private 的区别?
Swift 中有个5个级别的访问控制权限,从高到低依次是 open, public, internal, fileprivate, private
它们遵循的基本规则: 高级别的变量不允许被定义为低级别变量的成员变量,比如一个 private 的 class 内部允许包含 public的 String值,反之低级变量可以定义在高级别变量中;
* open: 具备最高访问权限,其修饰的类可以和方法,可以在任意 模块中被访问和重写.
* public: 权限仅次于 open,和 open 唯一的区别是: 不允许其他模块进行继承、重写
* internal: 默认权限, 只允许在当前的模块中访问,可以继承和重写,不允许在其他模块中访问
* fileprivate: 修饰的对象只允许在当前的文件中访问;
* private: 最低级别访问权限,只允许在定义的作用域内访问
[https://blog.csdn.net/watertekhqx/article/details/90701418](https://blog.csdn.net/watertekhqx/article/details/90701418)
swift 中关于open ,public ,internal,fileprivate,private 修饰的说明
open:
用open修饰的类可以在本某块(sdk),或者其他引入本模块的(sdk,module)继承,如果是修饰属性的话可以被此模块或引入了此某块(sdk)的模块(sdk)所重写
public:
类用public(或级别更加等级更低的约束(如private等))修饰后只能在本模块(sdk)中被继承,如果public是修饰属性的话也是只能够被这个module(sdk)中的子类重写
internal
是在模块内部可以访问,在模块外部不可以访问,a belong A , B import A, A 可以访问 a, B 不可以访问a.比如你写了一个sdk。那么这个sdk中有些东西你是不希望外界去访问他,这时候你就需要internal这个关键字(我在导入第三方框架时发现其实没有定义的话sdk里面是默认internal的)
fileprivate
这个修饰跟名字的含义很像,file private 就是文件之间是private的关系,也就是在同一个source文件中还是可以访问的,但是在其他文件中就不可以访问了 a belong to file A, a not belong to file B , 在 file A 中 可以访问 a,在 file B不可以访问a
private
这个修饰约束性比fileprivate的约束性更大,private 作用于某个类,也就是说,对于 class A ,如果属性a是private的,那么除了A外其他地方都不能访问了(fileprivate 和private都是一种对某个类的限制性约束。fileprivate的适用场景可以是某个文件下的extension,如果你的类中的变量定义成了private那么这个变量在你这个类在这个类的文件的拓展中就无法访问了,这时就需要定义为fileprivate)
最后是 Guiding Principle of Access Levels (访问级别的推导原则):不能在低级别的修饰中定义比自身更高的级别修饰,如public不能修饰在private类中的属性
6.关键字:Strong,Weak,Unowned 区别?
1. Swift 的内存管理机制同OC一致,都是ARC管理机制; Strong,和 Weak用法同OC一样
2. Unowned(无主引用), 不会产生强引用,实例销毁后仍然存储着实例的内存地址(类似于OC中的unsafe_unretained), 试图在实例销毁后访问无主引用,会产生运行时错误(野指针)
7.如何理解copy-on-write?
苹果建议当复制大的值类型数据的时候,使用写时复制技术,那什么是写时复制呢?我们现在看一段代码:
值类型(比如:struct),在复制时,复制对象与原对象实际上在内存中指向同一个对象,当且仅当修改复制的对象时,才会在内存中创建一个新的对象
为了提升性能,Struct, String、Array、Dictionary、Set采取了Copy On Write的技术
比如仅当有“写”操作时,才会真正执行拷贝操作
对于标准库值类型的赋值操作,Swift 能确保最佳性能,所有没必要为了保证最佳性能来避免赋值
var array1: [Int] = [0, 1, 2, 3]
var array2 = array1
print(address: array1) //0x600000078de0
print(address: array2) //0x600000078de0
array2.append(4)
print(address: array2) //0x6000000aa100
我们看到当array2的值没有发生变化的时候,array1和array2指向同一个地址,但是当array2的发生变化时,array2指向地址也变了,很奇怪是吧。
网友评论