IOS-swift学习笔记(持续更新)

目录

基础知识

获取字符串长度

swich case语句 

数组的创建

 ​编辑

数组的编辑

​编辑

数组的排序

​编辑

数组的遍历

​编辑

字典的增删改查

​编辑

函数

设置可变的函数参数数量

 函数的嵌套

常用的内置函数

枚举

类的初始化

类的set和get 

 类的静态方法

类的析构函数

​编辑

闭包

计算属性

存储属性的属性观察者

类型属性 

访问权限

 ​编辑

值类型和引用类型


基础知识

  • 四种输出方式:

IOS-swift学习笔记(持续更新)_第1张图片

  •  整数类型和实例属性,Swift提供的有符号和无符号类型有8、16、32、64位形式,能分别访问他们属性中的最大值和最小值,通常情况下不用自己设定,会根据应用的运行环境自动调节大小,并且Swift还提供了一些用于整形数据的实用函数。

IOS-swift学习笔记(持续更新)_第2张图片

  •  浮点数据实用函数

IOS-swift学习笔记(持续更新)_第3张图片

  • Swift中的字符是一个可拓展的字符集

IOS-swift学习笔记(持续更新)_第4张图片

  •  字符串判空

IOS-swift学习笔记(持续更新)_第5张图片

  • 字符串拼接 

IOS-swift学习笔记(持续更新)_第6张图片

  •  寻找子字符串

如果只需判断字符串的前部分和后部分是否与另一个字符串相同,可以使用hasPrefix()方法和hasSuffix()方法,分别用来判断一个字符串的前面或者后面是否包含某个字符串。

IOS-swift学习笔记(持续更新)_第7张图片

  • 字符串的大小写转换

可以使用uppercased()和lowercased()方法进行英文字符串的大小写转换。 

IOS-swift学习笔记(持续更新)_第8张图片

  • 字符串的截取和替换

IOS-swift学习笔记(持续更新)_第9张图片

  •  字符串的遍历
var num = 0
let hello = "13028833012"
for temp in hello.characters
{

    if temp == "1"
    {
       num += 1
    }
}
print(num)//结果为2
  • 元组可以从左到右进行值的比较
(2,3)>(1,3)//true
("Class1",98)>("Class2",54)//flase
(7,"Sunday")==(7,"Sunday")//true

获取字符串长度

swich case语句 

IOS-swift学习笔记(持续更新)_第10张图片

swift 中的switch匹配到一条case就会完成整个switch语句 ,可通过fallthrough进入到下一个case。

IOS-swift学习笔记(持续更新)_第11张图片

数组的创建

 IOS-swift学习笔记(持续更新)_第12张图片

数组的编辑

swift提供了数组的添加修改和删除方法

IOS-swift学习笔记(持续更新)_第13张图片

数组的排序

IOS-swift学习笔记(持续更新)_第14张图片

数组的遍历

IOS-swift学习笔记(持续更新)_第15张图片

字典的增删改查

IOS-swift学习笔记(持续更新)_第16张图片

函数

设置可变的函数参数数量

定义函数时,如果不确定参数的数量,可通过在变量类型后面加...定义可变参数。一个函数最多有一个可变参数,且必须是函数表中的最后一个,为避免在调用函数时产生歧义。

func get Average(numbers: Double...) -> Double{}

 函数的嵌套

import UIKit
func chooseNumber(needBigger: Bool,number1: Int,number2: Int)
{
    func getSmaller()
    {
        print((number1 < number2) ? number1 : number2)
    }
    
    func getBigger(){
        print((number1 > number2) ? number1 : number2)
    }
    needBigger ? getBigger : getSmaller
}

常用的内置函数

abs绝对值函数

min最小值函数

max最大值函数

filter函数:通常用于查找在数组元素中满足指定条件的元素

map函数:通常用于将数组中的每个元素通过指定的方法进行转换

reduce函数:可以把数组元素组合计算为一个值,比如将数组中的每个数字进行相加或相乘

IOS-swift学习笔记(持续更新)_第17张图片

枚举

enum UserLevel
{
case 总经理
case 主管
case 区域经理,业务员
}
enum Gender: UInt8
{
case Male = 1,Female,Unknow
}
print(Gender.Female.rawValue)

类的初始化

class Car
{
var brand: String
var speed: Int
init()
{
self.brand = ""
self.speed = 0
}
}

类的属性必须初始化

类的set和get 

类属性的set和get方法,获取时调用get,设置时调用set

IOS-swift学习笔记(持续更新)_第18张图片

 类的静态方法

IOS-swift学习笔记(持续更新)_第19张图片

类的析构函数

当类当实例引用计数为0时,系统会自动调用析构函数,无法手动调用。 

IOS-swift学习笔记(持续更新)_第20张图片

闭包

import UIKit

//函数
func test1(a: String, b: String) -> String {
    return a + b
}
print(test1(a: "hello,", b: "swift"))

//闭包
let test = { (a: String, b: String) -> String in
    return a + b
}
//调用闭包时,不要指定它的外部参数
print(test("hello,", "swift"))
import UIKit

let test = {10}
print(test())

let test2 = {print($0,$1,$2)}
test2(10,20,30)

尾随闭包:

闭包是最后一个参数,按下回车,即可转变为尾随闭包。

import UIKit

func calculate(a: Int,b: Int,fn: (Int,Int) -> Int) -> Int {
    return fn(a,b)
}

let value1 = calculate(a: 1, b: 2, fn: { (x,y) in
    x + y
})
print(value1)

let value2 = calculate(a: 3, b: 4) { x, y in
    x * y
}
print(value2)

let value3 = calculate(a: 10, b: 20, fn: {$0 - $1})
print(value3)

let value4 = calculate(a: 20, b: 5) {$0 / $1}
print(value4)

捕获变量:

import UIKit

func generator() -> () -> Int{
    var total = 0, step = 1
    
    func fn() -> Int {
        total += step
        return total
    }
    
    return fn
}

let next = generator()
print(next())//1
print(next())//2

let next2 = generator()
print(next2())//1
print(next2())//2

let next3 = next2
print(next3())//3
print(next3())//4

自动闭包:

自动闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。

自动闭包只有一行代码且需要加标识@autoclosure

import UIKit

func make_autoclosure(_ closure: @autoclosure () -> String){
    print("do_autoclosure \(closure())")
}

var array = ["a","b","c","d"]
make_autoclosure(array.remove(at: 0))//a
import UIKit

func myasset(_ closure: @autoclosure () -> Bool,_ str: String?){
    if closure(){
        if str != nil{
            print(str!)
        }
    }
}

myasset(1<2, "条件为真")

逃逸闭包:

比如loadData方法进行网络请求,当网络响应后调用闭包,可是loadData这个方法早已经执行完毕,这样闭包就脱离了loadData方法的作用域,并还持有相关对象的引用。

逃逸闭包能规避循环引用的风险 

import UIKit

typealias ResponseBlock = (_ data: Dictionary?,_ error: Error?) -> Void

func getRequest(url: String,body: Dictionary?,_ handle: @escaping ResponseBlock) {
    handle(Dictionary(),nil)
}

class Test {
    var url = "http://www.baidu.com"
    
    func testEscaping(){
        getRequest(url: url, body: nil) { (data, error) in
            print(self.url)//此处必须显示地引用self,否则编译错误
        }
    }
}

let tt = Test()
tt.testEscaping()
import UIKit

var handlers: [() -> Void] = []

func test(hander: @escaping () -> Void) {
    handlers.append(hander)
}
//在该例子中,闭包作为参数并没有在方法结束前调用,而是储存在数组了,闭包调用和结束时机是不可预知的,所以应使用逃逸闭包

计算属性

import UIKit

struct Rect{
    var originX: Double
    var originY: Double
    var width: Double
    var height: Double
    
    //可以使用同级的属性
    var centerX: Double{
//从外部读取时会触发get操作
        get{
            let centerX = originX + width / 2
            return centerX
        }
        //赋予新值设置新属性
        set(newCenterX){
            originX = newCenterX - width / 2
        }
    }
    var centerY: Double{//必须标明类型
        get{
            let centerY = originY + height / 2
        return centerY
        }
        set{
            originY = newValue - height / 2
        }
    }
    
    //只读,只能进行读取不能进行修改;只有一个getter可以省略get
    var area: Double{
        get{
            width*height
        }
    }
}



var square = Rect(originX: 0, originY: 0, width: 10, height: 10)
//触发get代码
let initialSquareCenterX = square.centerX
let initialSquareCenterY = square.centerY

//触发set代码
square.centerX = 15
square.centerY = 15

 面向对象的写法

struct Point{
    var x = 0.0, y = 0.0
}

struct Size{
    var width = 0.0, height = 0.0
}

struct Rect{
    var origin = Point()
    var size = Size()
    var center: Point{
        get{
            let centerX = origin.x + size.width / 2
            let centerY = origin.y + size.height / 2
            return Point(x: centerX, y: centerY)
        }
        set(newCenter){
            origin.x = newCenter.x - size.width / 2
            origin.y = newCenter.y - size.height / 2
        }
    }
}
var square = Rect(origin: Point(x: 0, y: 0), size: Size(width: 10, height: 10))
let initialSquareCenter = square.center
square.center = Point(x: 15, y: 15)

存储属性的属性观察者

import UIKit

//给存储属性设置属性观察者
class Product{
    //给初始值或用初始化构造器都不会调用willset和didset
    var price = 0{
        willSet(newPrice){//自定义变量名,原名newValue
            //给属性赋值之前调用
            print(newPrice)
        }
        didSet{
            //给属性赋值之后调用
            print(oldValue)
        }
    }
}
let product = Product()
product.price = 8

实际应用

//给存储属性设置属性观察者
class Product{
    //给初始值或用初始化构造器都不会调用willset和didset
    var price = 5000{
        willSet(newPrice){//自定义变量名,原名newValue
            //给属性赋值之前调用
            print(newPrice)
        }
        didSet{
            //给属性赋值之后调用
            print(oldValue)
            if price < 4000{
                print("通知用户:商品已经降价到您的心理价位了")
            }
        }
    }
}
let product = Product()
product.price = 3999

存储属性用于class,struct

计算属性用于class,struct,enum

属性观察者用于:

1.当前类中新定义的或继承自父类的存储属性

2.继承自父类的计算属性(当前类中新定义的直接使用setter) 

类型属性 

import UIKit

struct User{
    var name = "张三"
    static let standard = User()
}
User.standard
//类型属性:静态属性+类属性
//static虽然可以在类/结构体或枚举中使用,且可以修饰存储属性/计算属性和方法,非常通用,但他修饰的计算属性不能被重写
//class虽然只能在类中使用,且只能修饰类中的计算属性和方法,但修饰的计算属性和方法可以被重写
//总结:若无重写需求,则统一用static,性能更高

 类型属性:静态属性+类属性
static虽然可以在类/结构体或枚举中使用,且可以修饰存储属性/计算属性和方法,非常通用,但他修饰的计算属性不能被重写
class虽然只能在类中使用,且只能修饰类中的计算属性和方法,但修饰的计算属性和方法可以被重写
总结:若无重写需求,则统一用static,性能更高

访问权限

 IOS-swift学习笔记(持续更新)_第21张图片

private只能在该文件该作用域内使用

fileprivate只能在同一个swift文件内使用

internal是默认访问权限在同一个modual中使用

public可用于开发第三方功能包时使用

open只能修饰class以及class内的属性和方法,除了public权限外还能在别的modual中实现对该modual的继承和重写

值类型和引用类型

值类型存栈中。

引用类型存堆中,会在栈中存一个他的引用地址。

let修饰的引用类型,仍旧可以修改他下面的属性(因为栈中存的是地址),而struct不可以。

值类型中的内容不能随意改变,必须复制一份才能修改,使用mutating关键字可复制一份。

import UIKit

//内存:栈(stack),堆(heap)

struct StructPerson{
    var name: String
    var gender: String
    mutating func changeName(name: String){
        self.name = name
    }
}
//值类型-value type-数据直接存在栈中(除class和function/闭包之外都是值类型)
//优点:简单,快,可以深拷贝,真正的不变性,不会内存泄露(后述)
var structPerson1 = StructPerson(name: "张三", gender: "男")
var structPerson2 = structPerson1 //深拷贝
structPerson2.name = "张大花"
structPerson1.name

//let a = 1
//a = 3
//let structPerson3 = StructPerson(name: "李四", gender: "男")
//structPerson3.name = "李大花"

class ClassPerson{
    var name: String
    var gender: String
    init(name: String , gender: String) {
        self.name = name
        self.gender = gender
    }
    func changeName(name: String){
        self.name = name
    }
}
//引用类型-reference type-数据在栈中存储的是它的引用地址(真正存在堆中)
//优点:可以继承
var classPerson1 = ClassPerson(name: "张三", gender: "男")
var classPerson2 = classPerson1 //浅拷贝
classPerson2.name = "张大花"
classPerson1.name

let classPerson3 = ClassPerson(name: "李四", gender: "男")
classPerson3.name = "李大花" //虽然定义为let,但仍旧可以修改里面的属性

你可能感兴趣的:(ios,ios,swift,学习,开发语言)