1.类型修饰符
?可变类型,代表该变量可能没有值,!代表该变量一定有值。
?修饰的变量,需要使用!解包使用,否则是可选类型
//0.? !修饰符
var str:String?
str="hi"
print(str)
print(str!)
var str2:String!
str2="ha"
print(str2!)
2.if条件语句
if语句不需要括号
let num:Int=10
if num<100
{
print(num)
}
3.for循环语句
let nums:[Int]=[10,20,30,40]
//不需要索引
for value in nums
{
print(value)
}
//需要索引
for (index,value) in nums.enumerated()
{
print(index,"+",value)
}
//forEach函数
nums.forEach {num in
print(num)
}
4.string
//String可变
var strT="ABC"
strT+="DEF"
print(strT)
//string连接变量
let index=6
strT+="\(index)个字母"
print(strT)
//string比较
let strA="A"
let strB="A"
if strA==strB
{
//string长度
print(strA.count,terminator: "")
print("相同")
}
5.数组和字典
//数组和字典的基本使用
let nums:[Int]=[5,2,3]
for num in nums
{
print(num)
}
let dicts:[Int:String]=[1:"hi",2:"ha"]
for dict in dicts
{
print(dict.key,dict.value)
}
6.函数
//函数定义
func sum(a:Int,b:Int)->Int
{
return a+b
}
//外部必须使用n1,n2参数名调用
func sum2(n1 a:Int,n2 b:Int)->Int
{
return a+b
}
//函数调用
print(sum(a: 10, b: 32))
print(sum2(n1: 1, n2: 1))
7.闭包
类比OC中的Block代码块,闭包作为变量,函数参数(尾随闭包),返回值的使用。
作为变量的闭包:
//闭包的定义
let testClosure={(a:Int,b:Int) ->Int in
return a+b
}
//闭包的调用
print(testClosure(3,8))
作为函数参数的闭包:
//尾随闭包,函数最后一个参数,使用闭包作为参数cl:(参数)->返回值
func multi(a:Int,b:Int,cl:(Int,Int)->Int)->Int
{
cl(a,b)
}
//尾随闭包的使用(){闭包体在括号后面}
let res=multi(a: 6, b: 7) { a, b in
return a*b
}
print(res)
作为返回值的闭包:
//参数是a,b,返回值是()->Double的闭包
func divide(a:Double,b:Double)->()->Double
{
func res()->Double
{
return a/b
}
return res;
}
let funcDivide=divide(a: 20.0, b: 2.0)
print(funcDivide())
8.类
属性和方法:
//普通属性
var num:Int=0
//类属性
static var Flag:Bool=true
//通过setget修改属性的值
var middle: Int {
get {
return num/2
}
set {
num = newValue
}
}
//通过willsetdidset监听属性的变化
var counter: Int = 0{
willSet(newTotal){
print("计数器: \(newTotal)")
}
didSet{
if counter > oldValue {
print("新增数 \(counter - oldValue)")
}
}
}
//类方法
static func getFlag()
{
print("flag",Flag)
}
//是否同一个对象或者类
let tc1=TestClass()
let tc2=TestClass()
if tc1===tc2
{
print("同一个对象")
}else
{
print("不同对象")
}
if tc1.isKind(of: TestClass.self)
{
print("类型相同")
}else
{
print("类型不同")
}
self.num=100
print("middle:",self.middle)
self.counter=100
self.counter=800
ViewController.getFlag()
ViewController.Flag=false
ViewController.getFlag()
下脚标语法:
//下脚标语法
var denum:Int=0
subscript(index: Int) -> Int {
return denum+index
}
denum=97
print(self[0])
print(self[1])
print(self[2])
继承:
import UIKit
//:表示继承,override表示重写方法 final表示该类不允许被继承
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
9.可选链
可选链可替代强制解析
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
//将导致运行时错误
let roomCount = john.residence!.numberOfRooms
想使用感叹号(!)强制解析获得这个人residence属性numberOfRooms属性值,将会引发运行时错误,因为这时没有可以供解析的residence值。
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
// 链接可选residence?属性,如果residence存在则取回numberOfRooms的值
if let roomCount = john.residence?.numberOfRooms {
print("John 的房间号为 \(roomCount)。")
} else {
print("不能查看房间号")
}
10.ARC
同OC一样,swift使用ARC管理内存,也存在强循环引用的情况
class Book{
var student:Student?
init(){
print("Book init")
}
deinit{
print("Book deinit")
}
}
//使用weak/unowned关键字解决循环引用的问题
class Student{
// unowned var book:Book?
weak var book:Book?
init(){
print("Student init")
}
deinit{
print("Student deinit")
}
}
var bk:Book?
bk=Book()
var stu:Student?
stu=Student()
bk?.student=stu
stu?.book=bk
stu=nil
bk=nil
11.类型转换
is 用于检测值的类型,as 用于转换类型。
向下转型,用类型转换操作符(as? 或 as!)
class Book{
var student:Student?
init(){
print("Book init")
}
deinit{
print("Book deinit")
}
}
class Story:Book{
}
class Dictionary:Book{
}
let sd:Story=Story()
if sd is Book
{
print("sd is Book")
}else
{
print("sd is not Book")
}
let dic:Dictionary=Dictionary()
let bks=[sd,dic]
for value in bks
{
if let res=value as? Story
{
print(value,"as Story")
}else
{
print(value,"as Dictionray")
}
}
Swift为不确定类型提供了两种特殊类型别名:
AnyObject可以代表任何class类型的实例。
Any可以表示任何类型,包括方法类型(function types)。
12.类扩展
扩展就是向一个已有的类、结构体或枚举类型添加新功能。
扩展可以对一个类型添加新的功能,但是不能重写已有的功能。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let num:Int=20
print(num.square)
print(num.multNum(num: 3))
}
}
extension Int{
//拓展属性
var square:Int{
return self*self
}
//拓展方法
func multNum(num:Int)->Int
{
return num*self
}
}
13.类协议
协议规定了用来实现某一特定功能所必需的方法和属性。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var stu:Student=Student(reading: true)
stu.writing()
stu.sleeping()
print(stu.reading)
}
}
//类中必须要实现协议中的属性和方法,在初始化方法中要对属性赋值
class Student:Live
{
var reading: Bool
init(reading:Bool) {
self.reading=reading
}
func writing() {
print("writing")
}
func sleeping() {
print("sleeping")
}
}
//协议可以继承
protocol Study{
//协议中属性生命get set
var reading:Bool{
get set
}
//协议中方法定义方法名称
func writing()->Void
}
protocol Live:Study{
func sleeping()->Void
}
14.泛型
//交换2个T类型的值
func swapTwoValues(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var num1=1
var num2=2
var string1="a"
var string2="b"
swapTwoValues(&num1,&num2)
swapTwoValues(&string1, &string2)
print(num1,num2)
print(string1,string2)
15.访问控制
public 可以访问自己模块中源文件里的任何实体,别人也可以通过引入该模块来访问源文件里的所有实体。
internal 可以访问自己模块中源文件里的任何实体,但是别人不能访问该模块中源文件里的实体。
fileprivate 文件内私有,只能在当前源文件中使用。
private 只能在类中访问,离开了这个类或者结构体的作用域外面就无法访问。