一,Swift中的类型有Class,enum,struct;其中Class是引用类型,其他两种是值类型。
二,引用类型的引用计数:
引用计数只是针对类的实例,没有结构体和枚举。结构体和枚举是值类型,不是引用类型,没有通过引用存储和传递。
闭包也属于引用类型;
三,循环引用:
weak,弱引用,类似于OC中的weak,当指向的对象被释放后,weak指针置为nil;
unowned,无主引用,类似于OC中的__unsafe_unretained,对象释放后,unowned指针不会置为nil,下次去发送消息会崩溃;
[unowned self] in , [weak self] in解决闭包中的循环引用问题;
详细:
https://www.cnswift.org/automatic-reference-counting
例子:
//闭包
lazy var asHtml : () -> String = {
[weak self] in
print("xxxx")
//这里调用了self,asHtml也属于self,造成了循环引用,所以得[weak self] in,
return self.debugDescription
}
四,lazy关键字类似于懒加载的作用;可修饰方法变量和属性变量,如果修饰方法,则方法内可以用self.去调用当前类中的变量。
//例子-1
lazy var userCenterListV : SKBaseTableView = {
let userCenterListV = SKBaseTableView(frame: .zero, style: .grouped);
userCenterListV.delegate = listDelegate;
userCenterListV.dataSource = listDelegate;
return userCenterListV;
}();
//例子-2
lazy var names: NSArray = {
let names = NSArray()
print("只在首次访问输出")
return names
}()
例如以下代码,解释lazy闭包的具体执行:
lazy var iconImagView: UIImageView = {
() -> UIImageView in
let iconImagView = UIImageView.init();
return iconImagView;
}()
定义了一个变量iconImagView,然后通过闭包返回一个UIImageView类型的实体,赋值给iconImagView,所以{ }为函数体,( )等于执行力函数,所以可以简写为,去掉参数和返回值:
lazy var iconImagView: UIImageView = {
let iconImagView = UIImageView.init();
return iconImagView;
}()
上边两种变量的初始化等价于:
lazy var iconImagView = tmpImageView();
func tmpImageView() -> UIImageView{
let iconImagView = UIImageView.init();
return iconImagView;
}
五,Swift访问级别关键字:
open , public , internal , fileprivate ,或 private 修饰符来定义访问级别。
默认为:internal
一个方法中,如果有参数是私有的,那么这个函数的定义必须得是私有的,否则编译会报错,例如:
//其中,SomeInternalClass传递过来的是一个私有属性
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// function implementation goes here
}
枚举中的独立成员自动使用该枚举类型的访问级别。例如一下枚举的类型是public,那么其中里边的成员也是public级别了。
创建子类时的访问级别不能高于父类的访问级别。
public enum CompassPoint {
case north
case south
case east
case west
}
属性的getter和setter方法进行级别设置:
private(set) var numberOfEdits = 0//说明只读,外部不能修改
private(get) var numberOfEdits = 0//只写,外部不能访问
public private(set) var numberOfEdits = 0,两种修饰,public修饰get级别,private修饰set级别。
六,自定义一个坐标加/减法。
struct Vector2D {
var x = 0.0, y = 0.0
}
extension Vector2D {
static func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
//
extension Vector2D {
static prefix func - (vector: Vector2D) -> Vector2D {
return Vector2D(x: -vector.x, y: -vector.y)
}
}
七,遵循Equatable协议的直接可以进行比较
Swift 为以下自定义类型提等价运算符供合成实现:
1,只拥有遵循 Equatable 协议存储属性的结构体;
2,只拥有遵循 Equatable 协议关联类型的枚举;
3,没有关联类型的枚举。例如:
struct Strt_2D: Equatable {
var x = 0.0,y = 0.0;
}
//
let fir2D : Strt_2D = Strt_2D(x: 2.0, y: 3.0);
let sec2D : Strt_2D = Strt_2D(x: 1.0, y: 3.0);
if fir2D == sec2D{
print("相等")
}else{
print("不相等")
}
//输出不相等
自定义运算符:
prefix operator +++ {}
static prefix func +++ (vector: inout Vector2D) -> Vector2D {
vector += vector
return vector
}
infix operator +- { associativity left precedence 140 } //优先级
八,关键字is判断当前实例是否属于一个特定的类,返回bool,is是类型检查操作符,只能对其类的实例进行操作判断。
as,将某个实例转换成其对应的类型;
as直接进行转换;
as!,强制转换,如果类型不符,那么运行也会错误;
as?,可选转换,如果类型不符,转换返回nil;
let selfObj = self as SKBaseViewController; selfObj.test = "asdkjadsjjladsl"; //其实就是类似于OC里边的转换 (UIVLabel *)self.view;
Anyobject和Any类似于OC中的id类型,不确定具体的实例类型。
Anyobject可以表示class类型的实例;
Any可表示class,枚举,结构体类型的实例;
where关键字,类似于mysql中的约束条件,增加约束,例如:
case let someDouble as Double where someDouble > 0:
nil,nil只能赋值给一个非可选的常亮或者变量,也就是如果不是?修饰的,那么则不能赋值为nil,同理,如果?修饰的变量或者常量,在定义的时候,系统会初始化其值为nil。
九,? ! 缺省值和展开;
?,告诉系统,当前变量可以被赋值为nil,swift中,如果创建的变量不被初始化,则会报错,那么需要用到缺省符号?,作用是系统会自动将一个变量在定义的时候赋值为nil,然后将其作为一个可选值,也就是说,当前被?修饰的变量,可以不用进行初始化,也不会报错。那么需要用到可选值的时候,需要进行展开。
缺省值也能调用自己的属性方法等,缺省变量的属性也是缺省值,例如:
let vars : String? vars = "阔以啊。"; print(vars?.utf8CString); //输出,Optional代表可选 Optional(ContiguousArray([-23, -104, -108, -28, -69, -91, -27, -107, -118, -29, -128, -126, 0]))
可选值的展开!:
1,!符号直接进行强制展开,可通过if判断,然后进行展开,否则如果! 后值为nil,为会崩溃。
//用!进行了强制展开
let vars : String?
vars = "阔以啊。";
if(vars != nil){
print(vars!);
}
对缺省值的属性进行强制展开:
print((vars?.utf8CString)!);
2,直接通过if赋值进行展开,不需要!,这里的if进行了3步操作,首先=进行赋值,然后判断新变量是否为空,如果不为空则!,也就是进行了展开,例如:
let vars : String?
vars = "阔以啊。";
if let var_ss = vars{
print("this is non optional var",var_ss);
}else{
print("....");
}
//输出:
this is non optional var 阔以啊。
3,通过guard关键字进行判断,类似于if,if是满足条件执行,guard不满足条件执行,例如:
var vars : String? = nil;
vars = "你好";
//这里如果不满足条件才会执行
guard nil != vars else {
print("no empty");
return;
}
//以下就可以全部进行强制转换,不怕为nil
print(vars!);
十,便利初始化器。
convenience init(_ groupedFrame:CGRect) {
self.init(frame: groupedFrame,style: .grouped);
}
十一,告知用户一些message,例如当前方法太久,已经有新方法代替他的时候。
@available(iOS, introduced: 2.0, deprecated: 13.0, message: "Use -[UIDevice userInterfaceIdiom] directly.") public func UI_USER_INTERFACE_IDIOM() -> UIUserInterfaceIdiom
十二,闭包,类似于OC Block。
//创建一个函数,传递一闭包参数
func bibao(task: () -> String) -> Void {
print(task());//执行了输出闭包,所以可以断言闭包是有返回值的。
}
//闭包参数的参数为空,返回值为String。
执行bibao()函数
var block : () -> String = {
return "我的名字";
}
//执行
bibao(task: block);直接将block闭包传给了bibao方法。
这里是自己定义了一个需要的闭包类型,如果直接传入:
bibao(task: {
() -> String in
return "你好啊啊啊";
})
//直接传入了,它的形式为:
{ (parameters) -> (return type) in
statements
}
//闭包的函数整体部分由关键字 in 导入,这个关键字表示闭包的形式参数类型和返回类型定义已经完成,并且闭包的函数体即将开始。
2,委托初始化器,一个init方法调用(委托)另外一个init进行初始化,此初始化方法为委托初始化器。
以下定义了5个初始化方法,一个类方法。
第一个初始化方法是重写了父类的初始化方法;
第二个,第三个是自生的init方法,调用了父类的init方法。
第四个系统的,第五个是便捷初始化器,一个类里边可以写多个便捷初始化器,需形参名不同。
override init(frame: CGRect, style: UITableView.Style){
super.init(frame: frame, style: style);
if #available(iOS 11.0, *){
self.contentInsetAdjustmentBehavior = .never;
self.estimatedSectionHeaderHeight = 0;
self.estimatedSectionFooterHeight = 0;
}
}
init(groupframe: CGRect) {
super.init(frame: groupframe, style: .grouped);
}
init(plainFrame: CGRect) {
super.init(frame: plainFrame, style: .plain);
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(_ groupedFrame:CGRect) {
self.init(frame: groupedFrame,style: .grouped);
}
static func initPlain(frame: CGRect) -> SKBaseTableView{
let plainList = SKBaseTableView.init(frame: frame, style: .plain);
return plainList;
}
convenience init(groupframe: CGRect) {
self.init(frame: groupframe, style: .grouped);
}
convenience init(plainFrame: CGRect) {
self.init(frame: plainFrame, style: .plain);
}
convenience init(_ groupedFrame:CGRect) {
self.init(frame: groupedFrame,style: .grouped);
}

