1、
swift5.1基础语法:https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
swift5大概语法:https://www.cnblogs.com/1-434/p/10512719.html
源码地址:链接:https://pan.baidu.com/s/1Nxy3uY32JdyxaMXsKlRyhQ 密码:csua
import UIKit
let hasLogin = true
let hadHash = hasLogin.hashValue
hasLogin.description
let starCount = 12
if starCount >= 12 {
print("hahahaha")
}
var a = 1.5
var b : Float = 2.5
var c = Float.infinity
var d : Double = 3.5
d + 0.5
d - 1.5
d * 2.0
//d� / 4
d.addProduct(1, 2)
d.advanced(by: 1.1)
d.distance(to: 16.0)
let hello = "hello"
let entity = "coolkeTang"
var helloEntity = hello + "." + entity
helloEntity += "end"
helloEntity.count
for char in helloEntity {
// print("char is \(char)")
}
let initStr = "1233"
Int(initStr)
var message : String = "You got 3 apples"
message.hasSuffix("apples") //是否有后缀
message.hasPrefix("You g") //是否有前缀
message.uppercased() //全部转大写
message.lowercased() //全部转小写
message.capitalized //每一个单词的首字母大写You Got 3 Apple
message.isEmpty
message.components(separatedBy: " ")
message.caseInsensitiveCompare("You got 3 apples").rawValue
message.caseInsensitiveCompare(message.uppercased()).rawValue
message.contains("apple")
message.distance(from: message.startIndex, to: message.endIndex)
message.lengthOfBytes(using: .utf8) //获得字符串在指定编码模式下的字节长度
message.range(of: "got")?.lowerBound
message.range(of: "got")?.upperBound
var shanghai = "上海"
shanghai.applyingTransform(StringTransform.toLatin, reverse: false)
message.append("ahaha")
message.insert("!", at: message.endIndex)
message.insert(contentsOf: "Hi", at: message.startIndex)
let index = message.index(message.startIndex, offsetBy: 3)
let startIndexZ = message.index(message.startIndex, offsetBy: 14)
let endIndexZ = message.index(message.endIndex, offsetBy: -17)
//let range = startIndexZ ..< endIndexZ
//print(message[range])
//message.replaceSubrange(range, with: "stars")
message = "I have 5 starts and you have 5 stars too";
message.replacingOccurrences(of: "stars", with: "apples")
let http500Error = (500, "Internal server error")
let (stateCode, stateMessage) = http500Error
//statecod
stateMessage
let tooBig : UInt8 = UInt8.max
//let onThousand: UInt8 = 1000
let stringArr = Array<String>()
let floatArr = [Float]()
var intArr = [1,2,3,4,5]
intArr.first
intArr.last
intArr.count
intArr.isEmpty
intArr.contains(3)
intArr.max()
intArr.min()
intArr.reverse()
intArr += [8,4,29]
intArr.append(100)
intArr.swapAt(2, 3)
//print("intArr is\(intArr)")
intArr[2...4] = [7,8] //将intArr[2],intArr[3],intArr[4] 替换为7,8,8
//print("chanage intArr is \(intArr)")
intArr.insert(20, at: 4)
intArr.sort()
intArr.sort(by: {$0 > $1})
//print("chanage intArr is \(intArr)")
//print("chanage1 intArr is \(intArr)")
intArr.dropFirst() //返回一个删除第一个元素后的 新数组
//print("chanage2 intArr is \(intArr)")
intArr
intArr.popLast() //删除数组的最后一个元素,返回删除的最后一个元素
//print("chanage2 intArr is \(intArr)")
intArr.remove(at: 1) //删除指定角标额元素并返回删除的元素
//print("chanage3 intArr is \(intArr)")
intArr
var numberArr1 = [1,2,3,4]
var numberArr2 = [5,6,7,8]
var numberArr = [numberArr1,numberArr1]
var newArr = Array<Array<Int>>()
newArr.append(numberArr1)
newArr.append(numberArr2)
for subArr in newArr {
for item in subArr {
// print(item)
}
}
var StringArr1 = [ "a" , "b" , "c" ]
for stringItem in StringArr1 {
// print(stringItem)
}
for i in 0 ..< StringArr1.count {
// print(StringArr1[i])
}
for (index, value) in StringArr1.enumerated()
{
// print("\(index):\(value)")
}
var airportDic : Dictionary<String,String> = ["DUB":"Dublin","TYO":"Tokyo"];
var firstStudent = ["Name":"Peter","Age":"12"];
var secondStudent : Dictionary<String,Any> = ["Name": "Peter", "Age": 16];
secondStudent["Name"]
secondStudent["Name"] = "Jon";
//print(secondStudent)
//secondStudent.count
secondStudent.description
secondStudent.isEmpty
secondStudent.updateValue(20, forKey: "Age")
print(secondStudent)
secondStudent.popFirst()
print(secondStudent)
secondStudent.removeValue(forKey: "Age")
secondStudent.isEmpty
print(secondStudent)
airportDic.removeAll()
firstStudent.first?.key
firstStudent.first?.value
firstStudent.reversed()
for key in firstStudent.keys {
print(firstStudent[key] ?? 1)
}
for value in firstStudent.values {
print(value)
}
for (key, value) in firstStudent {
print("key = \(key),value = \(value)")
}
var dicpts : Dictionary<String,Any> = ["i":"yi","d":"asdf","dd":"were","gdafds":"gadf"]
var keyA = dicpts.keys.sorted()
for key in keyA {
print(dicpts[key] ?? "wu")
}
**一元二元三元**
var a = 1
let b = -a
let x = false
let y = !x
//a++ 已经废弃
a += 1
a -= 1
a *= 2
a /= 2
9 % 4
//8 % 2.5 浮点型不能用于 求余运算符
8.truncatingRemainder(dividingBy:2.5)
"hello" + "world" // 拼接字符串
[1,2] + [3,4] //拼接数组
**位运算符**
位或 ( | ) 有1为1,全0为0
位与( & ) 有0为0,全0为1
位异或 ( ^ )相同为0,不同为1
et binaryBits : UInt8 = 0b00101011
let invertedBinaryBits = ~binaryBits
let firstBits : UInt8 = 0b11111100
let lastBits :UInt8 = 0b00111111
let resultBits = firstBits & lastBits
let outputBits = firstBits ^ lastBits
let shiftBits : UInt8 = 4
shiftBits << 2 //通过左移运算符,将整数的二进制数值左移两位,使整数的值放大到4倍
[swift位运算符详细介绍](https://www.yiibai.com/swift/swift_bitwise_operators.html)
[进制转换](https://blog.csdn.net/Limit_Fly/article/details/90708281)
**比较运算符和区间运算符**
1 == 1
2 != 1
for i in 1 ... 5 {
print(i)
}
for j in 1 ..< 5{
print(j)
}
let isMale = true
let isFemale = false
isMale && isFemale
isMale || isFemale
(isMale && isFemale) && (isMale || isFemale)
**循环语句**
for _ in 1 ..< 5 {
print("You get a star.")
}
for i in 1 ... 5 {
print(i)
}
for itemArr in [1,3,5] {
print(itemArr)
}
let url = "www.mob.com"
for charS in url {
print(charS)
}
**for循环求最小值**
let cardNumber = [
"Clubs":[22,32,54,83,100],
"Hearts":[67,101,23,-1],
"Square":[122,34,1]
]
var min = Int.max
for (_,valueArr) in cardNumber {
for (item) in valueArr {
if min > item {
min = item
}
}
}
print(min)
**switch-case**
let time = 20
var message = ""
switch time {
case 7:
message = "It is time to get up"
case 8,12,18:
message = "It is time to eating"
case let x where x > 18 && x < 24:
message = "Happy time"
case 1 ... 6:
message = "It is time for rest";
default:
message = "you had dead"
}
**contine ,break, fallthrough **
var sum = 0
for i in 1 ... 4 {
if i == 2 {
continue
}
sum += i
}
sum
let time = 6
var description = "It is"
switch time {
case 2,3,6,10:
description += " \(time) o'clock" //"It is 6 o'clock"
fallthrough
case 100:
description += " hahah" //"It is 6 o'clock hahah"
default:
description += "."
}
**if 和 if let 语句**
var i = 2
while i < 6 {
i += 1
}
var j = 2
repeat{
j += 1
}while j < 6
j
var optionalName : String? = "world"
var greeting = "Hello"
if let name = optionalName {
print(greeting + name)
}
**创建方法**
func sayHelloSwift()
{
print("Hello, Swift")
}
sayHelloSwift()
func sayHelloSwift(to: String)
{
print("Hello, \(to)")
}
sayHelloSwift(to: "Xcode")
func saySomething() -> String
{
return "Hello, badGirl"
}
let sayWhat = saySomething()
func sayGreeting(to: String) -> String
{
return "haah"
}
let sayGreetingStr = sayGreeting(to: "xcode")
func getDistance(startPoint point1: CGPoint, endPoint point2: CGPoint) -> CGFloat
{
let xDistance = point1.x - point2.x
let yDistance = point1.y - point2.y
return xDistance * yDistance
}
let p1 = CGPoint(x:0,y:0)
let p2 = CGPoint(x: 100, y: 100)
let xy = getDistance(startPoint: p1, endPoint: p2)
func getDistance(point1: CGPoint, point2: CGPoint) -> CGFloat
{
let xDistance = point1.x - point2.x
let yDistance = point1.y - point2.y
return sqrt(xDistance * xDistance + yDistance * yDistance)
}
let xyDistance = getDistance(startPoint: p1, endPoint: p2)
**无限参数**
注意:
一个函数最多只能拥有一个可变参数。
func getAverage(numbers: Double ...) -> Double
{
if numbers.count == 0 {
return 0.0
}
var total: Double = 0.0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
print(getAverage())
getAverage(numbers: 1,2,3,4)
**输入输出参数**
作为输入输出参数进行修改。
输入输出参数:定义一个输入输出参数时,在参数定义前加 inout 关键字。一个输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。
你只能传递变量给输入输出参数。你不能传入常量或者字面量,因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数名前加 & 符,表示这个值可以被函数修改。
func swap(a: inout Double, b: inout Double)
{
let temp = a
a = b
b = temp
}
var myScore = 6.5
var yourScore = 9.0
swap(&myScore, &yourScore) //调用函数,并在变量名称之前放置一个连字符(&),表示可以
**方法函数默认参数值**
默认参数传值了用传的值, 默认参数未传值是用默认值
func getDistance(startPoint: CGPoint,endPoint: CGPoint = CGPoint(x: 0, y: 0)) -> CGFloat
{
let xDistance = startPoint.x - endPoint.x
let yDistance = startPoint.y - endPoint.y
return sqrt(xDistance * xDistance + yDistance * yDistance)
}
let p1 = CGPoint(x: 100, y: 100)
let p2 = CGPoint(x: 200, y: 200)
getDistance(startPoint: p1, endPoint: p2)
getDistance(startPoint: p2)
****
func getTotal(number1: Int, number2: Int) -> Int
{
return number1 + number2
}
func getBigger(num1: Int, num2: Int) -> Int
{
return num1 > num2 ?num1 : num2
}
func getMathResult(function:(Int,Int) -> Int, a:Int, b:Int) -> Int
{
return function(a,b)
}
getMathResult(function: getTotal(number1:number2:), a: 10, b: 20);
getMathResult(function: getBigger(num1:num2:), a: 20, b: 10)
**解析函数类型**
func getTotal(number1: Int, number2: Int) -> Int
{
return number1 + number2
}
getTotal(number1: 1, number2: 1)
let newFunction:(Int,Int) -> Int = getTotal(number1:number2:)
newFunction(1,1)
let otherFunction = getTotal(number1: 1, number2: 1)
func printHelloWift()
{
print("Hello Swift")
}
let anotherGreeting: () -> () = printHelloWift //无参数无返回值的函数用()-> ()表示
anotherGreeting()
**使用函数类型作为返回值**
func stepForword(input : Int) -> Int
{
return input + 1
}
func stepBackward(input : Int) -> Int
{
return input - 1
}
func chooseStepFunction(isBack : Bool) -> (Int) -> (Int)
{
isBack ? stepBackward(input:) : stepBackward(input:)
}
let move = chooseStepFunction(isBack: false)
move(0)
**多个返回值**
func caculate(string: String) -> (vowels: Int, consonats: Int, others: Int)
{
var vowels = 0
var consonats = 0
var others = 0
for char in string {
switch String(char).lowercased() {
case "a", "e", "i", "0", "u":
vowels += 1
case "b", "c", "d", "f","g", "h", "j", "k", "l","n","p","q","r","s","t","v","w","x","y","z":
consonats += 1
default:
others += 1;
}
}
return(vowels,consonats,others)
}
caculate(string: "Hello, Swift!")
**方法里面嵌套方法**
func chooseFunctino(isteap: Bool) -> (Int)
{
func stepForword(forword: Int) -> (Int)
{
return forword + 1
}
func stepAfter(after: Int) -> (Int)
{
return after - 1
}
return isteap ? stepAfter(after: 1) : stepForword(forword: 2)
}
chooseFunctino(isteap: 1 > 2)
**函数的递归思想**
func recursion(n:Int) -> Int
{
if n <= 1 {
return 1
}else{
return recursion(n: n-1) + recursion(n: n-2)
}
}
recursion(n: 8)
**swift常用的函数**
abs(-32) //绝对值
assert(true)
max(1, 2)
max(1, 2, 3, 4)
min(1, 2)
print("Hello","world")
debugPrint("Hello","world")
print("I", "have", 5, "starts",separator: " ... ", terminator: "?\n")
let zoroes = repeatElement("start", count: 5) //重复元素生成数组
for x in zoroes
{
print(x)
}
var a = "siwft"
var b = "xcode"
swap(&a, &b)
a
b
type(of: "aa") //获取参数的类型
type(of: 1)
type(of: 1.5)
for i in (1 ... 10).filter({$0 % 3 == 0}) { //过滤函数,身下3的整数
print(i)
}
for i in (1 ... 4).map({$0 * 3}) { // mapi对参数做闭包处理,都乘以3
print(i)
}
let result = (1 ... 4).reduce(1, {$0 + $1}) // 1 和 数组元素累加的值
print(result)
**枚举,遍历枚举**
enum Orientaion
{
case North
case South
case East
case West
}
Orientaion.North
enum Fruit
{
case Apple, Banana, Orange, Peach, Watermelon
}
var myFavorite = Fruit.Apple
myFavorite = .Orange
var planet = Orientaion.East
switch planet{
case .East:
print("haahah")
default:
print("where is ");
}
enum ASCIIChar : Character
{
case Tab = "\t"
case LineFeed = "\n"
case CarriageRetur = "\r"
}
print(ASCIIChar.Tab)
**给枚举类型添加方法**
enum Language: Int
{
case Swift = 2
case ObjectiveC
case Unknow
func description()
{
if self == .Swift {
print("Coding in swift")
}else if self == .ObjectiveC {
print("Coding in ObjectiveC")
}else if self == .Unknow{
print("Coding in Unknow")
}
}
}
let swift = Language.Swift
swift.description()
swift.rawValue
Language.ObjectiveC.rawValue
**结构体下标**
struct Animal
{
var name: String = ""
var age: Int = 0
func say()
{
print("I am \(name).")
}
}
var animal = Animal(name: "Tiger", age: 2)
animal.say()
var animal2 = animal
animal2.name = "Bird"
print(animal2)
print(animal)
struct MySubscript
{
var num: Int
subscript(n: Int) -> Int // 使用subscript关键字给结构体添加一个下标操作,用来返回当前属性的值的指定倍数,使用下标可以访问集合或序列成员元素的快捷方式
{
return num * n
}
}
let subscr = MySubscript(num: 5) //对结构体初始化 并赋值
subscr[2] //最后对结构体对象使用下标操作
**类的初始化和调用**
class Person
{
var name: String
var age: Int
init() {
self.name = ""
self.age = 0
}
convenience init(name: String!, age: Int)
{
self.init()
self.name = name
self.age = age
}
func say() {
print("Hi, I am \(name), and \(age) years old.")
}
}
let person = Person()
person.name = "Jerry"
person.age = 35
person.say()
let secondPerson = Person(name: "bill", age: 32)
secondPerson.say()
**类的引用**
class Animal
{
var name: String
var age: Int
init(animalName: String, age: Int) {
self.name = animalName
self.age = age
}
func say() {
print("Hi, I am \(name)")
}
}
let animal = Animal(animalName: "Will", age: 20)
let animal2 = animal
animal2.name = "Tom"
animal.say() // Hi, I am Tom
animal2.say() // Hi, I am Tom
//animal和animal2对象 是一致的,改变一个,另一个也会改变
**类和结构体的对比**
struct Animal
{
var name: String
var age: Int
}
let tiger = Animal(name: "Tiger", age: 2)
var lion = tiger
lion.name = "lion"
print("tiger.name \(tiger.name),lion.name \(lion.name)")
打印:tiger.name Tiger,lion.name lion
class Person
{
var name : String
var age: Int
init() {
self.name = "Jerry"
self.age = 0
}
}
let person1 = Person()
let person2 = person1
preson2.name = "Tom"
print("person1.name \(person1.name) person2.name\(person2.name)")
打印:person1.name Tom person2.nameTom
总结:修改结构体参数用var修饰,赋值是深拷贝的 方式,修改一个对象的值,其他结构体 对象不影响,类的对象可以用let修饰,赋值是浅拷贝,修改一个其他参详也会变
**类的set和get方法**
class Player
{
var name : String = "Tom"
var level : Int = 3
var score: Double //给score参数手动设置get和set方法
{
get
{
name = "Lam"
return Double(level) * 2.0
}
set(newScore)
{
level = Int(newScore)/2
name = "Jim"
}
}
}
let player = Player()
player.score
print("name \(player.name),score \(player.score)")
打印结果:name Lam,score 6.0
player.score = 8
print("name \(player.name),score \(player.score)")
打印结果:name Jim,score 8.0
player.level
**类的析构函数**
class Animal1 {
var name: String
var age: Int
init(name: String,age: Int) {
self.name = "Tom"
self.age = 2
}
func say() {
print("I am \(name)")
}
deinit {
print("I`m deinited")
}
}
let animal: Animal1? = Animal1(name: "Jerry", age: 33)
类的析构函数:当引用计数为0 时自动调用析构函数deinit,通常在析构函数中释放一些资源(如移除通知等操作)
**类的下标**
下标是访问集合、列表、序列中的元素的快捷访问方式,结构体、枚举和类都可以定义下标
class Person1
{
var name: String = "Rocky"
var age: Int = 20
var height: Double = 130
subscript(index: Int) -> AnyObject
{
switch index
{
case 0:
return name as AnyObject
case 1:
return age as AnyObject
case 2:
return height as AnyObject
default:
return name as AnyObject
}
}
}
let person: Person1 = Person1()
let age = person[1]
let height = person[2]
let name = person[4]
**类的静态方法**
静态方法相当于OC的类方法,用类名调用
class MathTool
{
func alert() {
print("Caculating....")
}
func sum(num1: Int,num2: Int) -> Int {
alert()
return num1 + num2
}
class func multiply(num1: Int, num2: Int) -> Int{
return num2 * num1
}
}
let mathTool = MathTool()
mathTool.alert()
mathTool.sum(num1: 1, num2: 2)
MathTool.multiply(num1: 3, num2: 4)
**讲一个类的实例座位另一个类的属性**
懒加载:使用 lazy 修饰属性时,必须声明属性是变量。而且我们需要显示的指定属性的类型。对该属性进行一个赋值语句用来首次访问时使用。
class Animal
{
var name: String = "Lovely Dog"
var age = 1
}
class Person
{
var name = "Jerry"
var age: Int = 33
lazy var pet: Animal = Animal()
}
let person = Person()
person.name
person.age
person.pet.name
person.pet.age
**类的继承和重写**
class Animal
{
func say() {
print("I am animal....")
}
}
class Dog: Animal
{
var name: String
init(name: String) {
self.name = name
}
override func say() {
super.say()
print("I am a dog my name is \(name)")
}
}
var dog = Dog(name: "Tom")
dog.say()
**父类在实例转化中的应用**
class Animal
{
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Animal
{
var master: String
init(name: String,master: String){
self.master = master
super.init(name: name)
}
}
let creatures:[Animal] = [
Dog(name: "Nono", master: "Tom"),
Dog(name: "Bala", master: "Jim"),
Dog(name: "Baby", master: "Yam")
]
for object in creatures {
let dog = object as! Dog
print("name \(dog.name),master is \(dog.master)")
}
// as! 向下强制类型转换
**使用is语句检查实例的类型**
class Animal
{
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Animal
{
var master: String
init(master: String, name: String){
self.master = master
super.init(name: name)
}
}
class Bird: Animal
{
var food: String
init(food: String,name: String){
self.food = food
super.init(name: name)
}
}
let creatures: [Animal] = [
Dog(master: "Tom", name: "laha"),
Bird(food: "Jim", name: "jiza"),
Dog(master: "Zed", name: "wangwang")
]
var dogCount = 0
var birdCount = 0
for object in creatures {
if object is Dog {
dogCount += 1
}else if object is Bird{
birdCount += 1
}
}
print("dogcount is \(dogCount),birdcount is \(birdCount)")
for object in creatures {
if let dog = object as? Dog {
print("name is \(dog.name), master is \(dog.master)")
}else if let bird = object as? Bird{
print("name is \(bird.name), food is \(bird.food)")
}
}
**Any 任意类型**
var anything = [Any]()
anything.append(8)
anything.append(3.1415)
anything.append("hello")
anything.append((3.0,4.0))
anything
for item in anything {
switch item {
case let someInt as Int:
print(someInt)
case let someDouble as Double:
print(someDouble)
case let someString as String:
print(someString)
case let (x,y) as(Double,Double):
print(x,y)
default:
print("xixi")
}
}
/**as的用法
1, 子类向父类转换,向上
2,强制类型转换
3,switch语句是类型判断
**/
**使用extension对方法进行扩展**
extension Int
{
var double:Int{
return self * 2
}
var triple:Int{
return self * 3
}
var fourfold: Int{
return self * 4
}
var half: Double{
return Double(self) / 2
}
}
2.double 4
2.triple 6
2.fourfold 8
2.half 1
//扩展详解:[https://www.jianshu.com/p/0c963bc2194c](https://www.jianshu.com/p/0c963bc2194c)
**类的协议protocol**
protocol Walking
{
func walking()
}
protocol Eating {
func eating()
}
protocol Fighting:Walking{ // Fighting协议遵守Walking协议,用:冒号隔开
func fight()
}
class Animal: Fighting,Eating
{
func fight() {
print("Fighting ......")
}
func eating() {
print("eating ........")
}
func walking() {
print("walking .......")
}
func say(){
print("say ......")
}
}
let animal = Animal()
animal.fight() Fighting ......
animal.eating() eating ........
animal.walking() walking .......
animal.say() say ......
extension Animal
{
var weight: Double
{
get{
return 15.0
}
}
func getWeight() -> Double {
return 45.0
}
}
let secondAnimal = Animal()
secondAnimal.weight 15.0
secondAnimal.getWeight() 45.0
**?和!的用法**
var password: Optional<Any>
var password1:NSString?
print(password1?.length ?? 0)
var password3: NSString?
var password2:NSString?
print(password2?.length ?? 0 )
var password4: String! = "123456"
print(password4!.count)
class Pet
{
var name: String?
}
class Person
{
var name: String?
var pet: Pet?
}
let person = Person()
person.name?.count //?表示判断person.name的值,当person.name的值为空时,不在访问count参数
person.pet = Pet()
person.pet?.name
[参考2](https://www.jianshu.com/p/eacd24f0adaf)
**泛型函数**
func appendToGenericArray<T>(array1:[T], array2:inout [T]) //inout关键字修饰的字被修改会影响全局,影响函数外的值
{
for item in array1 {
array2.append(item)
}
}
// 在方法名后面用尖括号包含大写字母T,表示泛型函数,参数的类型也用T表示
var array = [1,2,3]
appendToGenericArray(array1: [6,5,4], array2: &array)
var arrayStr = ["2","4"]
var toArrayStr = ["hahah","lalal"]
appendToGenericArray(array1: arrayStr, array2: &toArrayStr)
func appendToGeneralString<T>(string:T,toString:T)
{
print(string)
}
appendToGeneralString(string: "ss", toString: "ssaa") //ss
appendToGeneralString(string: 1, toString: 3) // 1
appendToGeneralString(string: arrayStr, toString: toArrayStr) // ["2", "4"]
appendToGeneralString(string: array, toString: array) // [1, 2, 3, 6, 5, 4]
**do-try-catch**
enum ErrorType: Error
{
case invalidProduct
case insufficientCoins(coinsNeeded: Int)
case outOfStock
}
struct Product
{
var price: Int
var count: Int
}
class Shop
{
var totalCoins = 10
var products = [
"Pudding": Product(price: 12, count: 7),
"Dount": Product(price: 10, count: 0),
"Cheesepuff":Product(price: 7, count: 11)
]
func sell(productName: String) throws {
guard let product = products[productName] else{
throw ErrorType.invalidProduct
}
guard product.count > 0 else {
throw ErrorType.outOfStock
}
guard totalCoins > product.price else {
throw ErrorType.insufficientCoins(coinsNeeded: product.price - totalCoins)
}
}
}
**析构函数**
class MathTool
{
var name: String
init(name: String) {
self.name = name
}
deinit {
print("----------- name")
}
}
var person:MathTool? = MathTool(name: "zhangsan")
var person1 = person
person1?.name = "lisi"
print("person.name \(person?.name ?? "2"),person1.name \(person1?.name ?? "1")")
var person2 = person
person1 = nil
person = nil
person2 = nil
打印结果:person.name lisi,person1.name lisi ----------- name
**相互循环引用和weak 弱引用修饰符**
class People
{
var name: String
var pet:Pet?
init(name: String) {
self.name = name
}
deinit {
print("----------- name")
}
}
class Pet
{
var name: String
weak var master: People? //添加weak修饰符,不添加会一直循环引用,dog和master对象无法释放
init(name: String) {
self.name = name
}
deinit {
print("Pet is deinitialized.")
}
}
var master:People?
var dog:Pet?
master = People(name: "zhangsan")
dog = Pet(name: "wangwang")
master?.pet = dog
dog?.master = master
master = nil
dog = nil
**懒加载**
class Demo
{
var url: NSString
lazy var completeURL: NSString = {
if self.url.hasPrefix("http://") {
return self.url
}else{
return "http://\(self.url)" as NSString
}
}() //记得加赠()括号
init(url:NSString) {
self.url = url
}
}
let demo = Demo(url: "www.coolketang.com")
demo //url有值,completeURL为nil
demo.url
demo.completeURL
demo //url有值,completeURL有值
**范围Range**
let closeRange: ClosedRange = 1...3
let intArray = [1,2,3,4,5,6,7]
intArray[closeRange]
let halfOpenRange = 1..<3
intArray[halfOpenRange]
var myUrl = "coolketang.com"
let startIndex = myUrl.index(myUrl.startIndex, offsetBy: 0)
let endIndex = myUrl.index(myUrl.endIndex, offsetBy: -10)
let myRange = startIndex ..< endIndex
let range = NSRange.init(location: 1, length: 2)
intArray[Range.init(range)!]
let myWebsite = myUrl as NSString
myWebsite.substring(with: NSRange.init(location: 1, length: 2))//截取部分字符串,substring是NSString类的方法,String强制转换为NSString
**CGPoint 和仿射变换CGAffineTransform**
let zeroPoint = CGPoint.zero
let x = zeroPoint.x
let y = zeroPoint.y
zeroPoint.debugDescription
zeroPoint.equalTo(CGPoint(x: 0, y: 0))
var secondPoint = CGPoint(x: 10, y: 10)
let transform:CGAffineTransform = CGAffineTransform.identity
let moveTranslation = transform.translatedBy(x: 10, y: 10) // 将仿射变换对象在水平和垂直方向各平移10点
let thirdPoint = secondPoint.applying(moveTranslation) // 将平移后的点对象赋值给thirdPoint
let rotateTransform = moveTranslation.rotated(by: 90 * 3.1415/180.0) //对仿射变换对象进行旋转90度,旋转角度d为弧度方式
let fouthPoint = thirdPoint.applying(rotateTransform)
**CGPoint**
let zeroSize = CGSize.zero
let size = CGSize(width: 20, height: 20)
size.debugDescription
let affineTransform: CGAffineTransform = CGAffineTransform.identity
let translation = affineTransform.translatedBy(x: 10, y: 10)
let tanslationSize = size.applying(affineTransform)
let scale1 = translation.scaledBy(x: 2.0, y: 3.0)
let scaleSize = size.applying(scale1)
let fifthSize = NSCoder.cgSize(for: "{200,100}") //使用系统接口可以使用字符串
**CGRect**
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
rect.debugDescription
let originPoint = CGPoint.zero
let size1 = CGSize(width: 100, height: 100)
let secondRect = CGRect(origin: originPoint, size: size1)
secondRect.origin.x
secondRect.origin.y
secondRect.size.width
secondRect.size.height
secondRect.width
secondRect.height
secondRect.minX
secondRect.maxX
secondRect.minY
secondRect.maxY
secondRect.contains(CGPoint(x: 10, y: 10)) //是否包含该点
secondRect.contains(CGRect(x: 10, y: 10, width: 10, height: 10)) //是否包含该区域
secondRect.equalTo(rect)
secondRect.insetBy(dx: 10, dy: 10) //截取secondRect区域的和边界相距10 的区域
secondRect.intersection(CGRect(x: 10, y: 10, width: 10, height: 200)) //获取 和另一个区域相交的部分
secondRect.intersects(CGRect(origin: originPoint, size: size1)) //判断两个区域是否相交
secondRect.offsetBy(dx: 10, dy: 10) //获取 区间水平和垂直各偏移10点之后的区域
secondRect.union(CGRect(x: 30, y: 30, width: 300, height: 300)) // 获取两个区域合并后的区域
NSCoder.cgRect(for: "{{0,0},{100,100}}") //和点对象,尺寸对象相同,同样可以将一个格式化的字符串,转换为区域对象
**字符串**
let string = NSString(string: "meet")
let floatString = NSString(format: "%f", 25.0)
var secondString = string.appending("coolketang.")
secondString.capitalized
secondString.caseInsensitiveCompare("test").rawValue //-1表示当两个字符串进行排序时,当前字符串位于进行比较的字符串前方 ,0表示两个字符串相同,1表示在比较的字符串后面,
secondString.commonPrefix(with: "meet swift") // 获取两个字符串相同的前缀
secondString.contains("coolketang")
secondString.data(using: .utf8) //返回该字符串urf8格式的数据
secondString.hasPrefix("meet")
secondString.hasSuffix("coolketang.") // 后缀是否包含这个
secondString.insert(".", at: secondString.endIndex) // 插入字符串到指定的位置
secondString.lengthOfBytes(using: .utf8) // 获取字符串在指定编码格式下的长度
secondString.count // 获取字符串中字符的数量
secondString.lowercased()
secondString.uppercased()
secondString.range(of: "meet")?.lowerBound //获得meet字符串在secondString中的起始和终点位置
secondString.range(of: "meet")?.upperBound
secondString.removeSubrange(secondString.range(of: "meet")!) //删除指定区间的字符串
secondString.replacingOccurrences(of: "cool", with: "swift") //将字符串存在的字符串替换成后面的字符串,不存在就不替换
secondString[secondString.index(secondString.startIndex, offsetBy: 2)] // 从指定的位置开始,往后偏移的字符,
**Date和DateFormatter**
var date = Date()
date.addTimeInterval(60*60)
let secondDate = date.addingTimeInterval(60*60)
secondDate.compare(date.addingTimeInterval(60*60)).rawValue
secondDate.description
secondDate.debugDescription
secondDate.timeIntervalSince(date) //截止到该时间的间隔
secondDate.timeIntervalSince1970
secondDate.timeIntervalSinceNow
let dateFormatter = DateFormatter() // 初始化一个日期格式化的对象
dateFormatter.locale = Locale.current //设置日期格式化d对象的本地属性
dateFormatter.dateStyle = DateFormatter.Style.full // 设置包含年月日星期的日期格式
dateFormatter.string(from: date) //查看该格式的日期
dateFormatter.dateStyle = DateFormatter.Style.long
dateFormatter.string(from: date)
dateFormatter.dateStyle = DateFormatter.Style.medium // Sep 17, 2020
dateFormatter.string(from: date)
dateFormatter.dateStyle = DateFormatter.Style.short // 9/17/20
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss" //12小时制 2020-09-17 07:10:22
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" //24小时制 2020-09-17 19:10:44
dateFormatter.string(from: date)
dateFormatter.dateFormat = "yyyy-mm-dd"
dateFormatter.string(from: date) //2020-02-19
dateFormatter.dateFormat = "yyyy-M-dd"
dateFormatter.string(from: date) // 2020-2-19
let dateString = "2017-06-02 19:15:59"
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let newDate = dateFormatter.date(from: dateString)
(newDate?.timeIntervalSinceReferenceDate)! > date.timeIntervalSinceReferenceDate
**日期组件DateComponent**
let date = Date()
let currentCalendar = Calendar.current
let dateComponents = currentCalendar.dateComponents([Calendar.Component.era,Calendar.Component.year,Calendar.Component.month,Calendar.Component.day,Calendar.Component.hour,Calendar.Component.second,Calendar.Component.minute], from: date) // 初始化date的日期组件
dateComponents.era // 1
dateComponents.year //2020
var component = DateComponents()
component.year = 2020
component.month = 09
component.day = 03
let dateComponent = currentCalendar.date(from: component) // 日期由日期组件 拼成显示
**Calendar和 时区Timezone**
var calendar: Calendar = Calendar.current
calendar.locale = Locale(identifier: "zh_CN")
calendar.timeZone = TimeZone(abbreviation: "EST")! //EST 美东时区的缩写
//calendar.timeZone = TimeZone(secondsFromGMT: +28800)! //距格林时间28800s的时区(中国时区)60*60*8 8个小时
calendar.firstWeekday = 2 //设置日历第一个工作日为2
calendar.minimumDaysInFirstWeek = 3; //设置第一周最小的天数为3
calendar.locale
calendar.timeZone
let date = Date()
calendar.isDateInToday(date)
calendar.isDateInTomorrow(date)
calendar.isDateInYesterday(date)
**NSTimer的使用**
class ViewController: UIViewController {
var appleCount = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// let timer = Timer(timeInterval: 1.0, repeats: false) { (timer) in
// print("hahhahah")
// }
// timer.fire()
// Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (scheduledtTimer) in
// print("scheduleTimer \(scheduledtTimer)")
// }
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.timerAction(_:)), userInfo: "an apple", repeats: true)
}
@objc func timerAction(_ timer:Timer)
{
if self.appleCount == 3 {
timer.invalidate()
return
}
let parameter = timer.userInfo as! String
print("I am eating \(parameter)")
self.appleCount += 1
}
}
**URL的使用**
let url = URL(string: "http://www.coolketang.com")
url?.absoluteString //获取url的字符串格式
var secondUrl = url?.appendingPathComponent("demo/login/")
//secondUrl?.deleteLastPathComponent() //获取当前目录的上一级目录
secondUrl?.host //域名
secondUrl?.lastPathComponent //获取url的最后一个目录
let thirdUrl = URL(string: "http://www.coolketang.com:8080/login.action?username=jerry")
thirdUrl?.port // 获得网址对象的端口号
thirdUrl?.query // 获取网址对象的查询参数
thirdUrl?.scheme // 获得网址对象的scheme
let targetPath:String = NSHomeDirectory() + "/Documents/music.png"
let fileUrl = URL(string: targetPath)
fileUrl?.pathComponents
fileUrl?.pathExtension //扩展名 png
**多线程**
**UIScreen获取屏幕信息**
UIScreen.main.availableModes.description
UIScreen.screens.count //屏幕数量
UIScreen.main.bounds //属性 屏幕的bounds
UIScreen.main.nativeBounds //属性 物理屏幕的像素
UIScreen.main.nativeScale //属性 设备物理屏幕的比例因子
UIScreen.main.brightness //属性 屏幕亮度等级
UIScreen.main.coordinateSpace.bounds //属性 当前屏幕的坐标空间
UIScreen.main.currentMode?.size
**UIColor**
UIColor.orange
UIColor.clear
let color = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
let secondColor = UIColor(white: 1.0, alpha: 0.5)
let thirdColor = UIColor(hue: 0.3, saturation: 0.75, brightness: 0.50, alpha: 1.00) //获取指定色相、饱和度、亮度、不透明度颜色模式下的颜色
let image = UIImage()
let thirdColor = UIColor(patternImage: image) //将图片转成color,平铺在界面
color.cgColor
color.withAlphaComponent(0.5)
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.backgroundColor = color
**swift语言的两种单例模式**
// 静态常量单例
final class SingleClass:NSObject //final可以防止类被继承,也可以防止类被重写方法,属性以及下标subscript,final不能用于结构体和枚举
{
static let shared = SingleClass() //static 定义一个静态常量,静态常量在实例调用结束后不会消失,并且保留原有值,即内存空间不会被释放,下次调用还能读取原有值
private override init() { //单例的构造器必须是private的,以防止其他对象也能创建出该单例类的实例
}
func say()
{
print("Hello,")
}
}
SingleClass.shared.say()
// 静态变量单例
final class SecondSingleClass: NSObject
{
static var secondSingleClass: SecondSingleClass //使用静态变量的方式创建单例
{
struct StaticS //借助结构体来存储类型变量,并使用let修饰符来保证线程的安全
{
static let instanceS: SecondSingleClass = SecondSingleClass()
}
return StaticS.instanceS
}
func say()
{
print("Hello,ahahahha")
}
}
SecondSingleClass.secondSingleClass.say()
**swift中的三种消息传递模式**
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let width = Int(self.view.frame.size.width - 40)
let greetButton = UIButton(frame: CGRect(x: 20, y: 100, width: width, height: 40))
greetButton.setTitle("Greeting", for: .normal)
greetButton.backgroundColor = UIColor.blue
// greetButton.addTarget(self, action: #selector(ViewController.ganshane(_:)), for: .touchUpInside)
// greetButton.addTarget(self, action: #selector(ganshane(_:)), for: .touchUpInside) //本类的点击事件方法可以省略掉方法前的类名
let buttonMethod: Selector = #selector(ganshane(_:)) //初始化选择器对象
greetButton.addTarget(self, action: buttonMethod, for: .touchUpInside)
greetButton.tag = 1
self.view.addSubview(greetButton)
let newSelector:Selector = #selector(calledByController)
// self.perform(newSelector) // 使用perform方法在子线程调用选择器
// self.perform(newSelector, with: nil, afterDelay: 2.0) //在子线程上调用选择器,传递参数为nil,并延长2秒
// self.perform(newSelector, on: .main, with: nil, waitUntilDone: true )
//选择在主线程中调用选择器,并等待动作的执行,
self.performSelector(inBackground: newSelector, with: nil) //选择在后台线程中h运行selector方法
}
@objc func ganshane(_ button:UIButton)
{
let tag = button.tag
print("button touchUpInside \(tag)")
}
@objc func calledByController()
{
print("perform calledByController")
}
@objc func delayMethod()
{
print("delayMethod-----")
}
}
**闭包在计时器,动画,线程中的使用**
class ViewController: UIViewController {
var animationView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer:Timer) in
print("Timer action .....")
}
animationView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0))
animationView.backgroundColor = .green
self.view.addSubview(animationView)
UIView.animate(withDuration: 3.0, animations: {
self.animationView.frame = CGRect(x: 200.0, y: 0.0, width: 40.0, height: 40.0)
}) { (Bool: Bool) in
print("Animation done")
}
Thread.detachNewThread { //新建一个线程
print("Do something on a new thread")
}
DispatchQueue.main.async {
print("DispatchQueue.main.async")
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
print("DispatchQueue.main.asyncAfter")
}
}
**两个对象调用 进行消息传递**
import UIKit
class CurrentView: UIView, UITextFieldDelegate {
var textField: UITextField!
weak var controller: ViewController? // 定义另一个对象
override init(frame: CGRect) {
super.init(frame: frame)
textField = UITextField.init(frame: self.bounds)
textField.font = UIFont.systemFont(ofSize: 14)
textField.textColor = .purple
textField.layer.shadowColor = UIColor.black.cgColor
textField.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
textField.layer.shadowOpacity = 0.45
textField.layer.shadowRadius = 3
textField.backgroundColor = .lightGray
textField.delegate = self
self.addSubview(textField)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.controller?.checkForm() // 引用顶一个对象的方法
return true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
import UIKit // 另一个对象的文件
class ViewController: UIViewController,UITextFieldDelegate {
var nameView : CurrentView!
var passwordView : CurrentView!
var submitButton : UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let width = Int(self.view.frame.size.width) - 40
let height = 40
nameView = CurrentView(frame: CGRect(x: 20, y: 80, width: width, height: height))
nameView.backgroundColor = .green
nameView.controller = self
self.view.addSubview(nameView)
passwordView = CurrentView(frame: CGRect(x: 20, y: 140, width: width, height: height))
passwordView.backgroundColor = .green
passwordView.controller = self
self.view.addSubview(passwordView)
submitButton = UIButton(frame: CGRect(x: 20, y: 240, width: width, height: height))
submitButton.setTitle("Sumbit", for: .normal)
submitButton.addTarget(self, action: #selector(sumbitForm(_:)), for: .touchUpInside)
submitButton.backgroundColor = .gray
submitButton.isEnabled = false
self.view.addSubview(submitButton)
}
@objc func sumbitForm(_ sender: UIButton)
{
print("sumbit login")
}
@objc func checkForm()
{
if nameView.textField.text != "" && passwordView.textField.text != "" {
submitButton.isEnabled = true
submitButton.backgroundColor = .yellow
}else{
submitButton.isEnabled = false
submitButton.backgroundColor = .gray
}
}
}
**swift中栈stack的使用,queue**
栈:先进后出
队列:先进先出
class Stack
{
var stack:Array<AnyObject>
init() {
stack = [AnyObject]()
}
func isEmpth() -> Bool {
return stack.isEmpty
}
func size() -> Int {
return stack.count
}
func push(object:AnyObject) {
stack.append(object)
}
func pop() -> AnyObject? {
if isEmpth() {
return nil
}else{
return stack.removeLast() //移除并返回最后一个元素
}
}
}
var stack = Stack()
stack.isEmpth() //true
stack.push(object: UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0))
stack.push(object: UIColor(red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0))
stack.pop() //(r:1.0,g:1.0,b:0.0,a:1.0)
//queue队列先进先出
class Queue
{
var queueArr:Array<Any>
init() {
queueArr = [Any]()
}
func isEmpty() -> Bool {
return queueArr.isEmpty
}
func push(object: Any) {
queueArr.append(object)
}
func pop() -> Any {
return queueArr.removeFirst()
}
}
var queue = Queue()
queue.isEmpty()
queue.push(object: 1)
queue.push(object: UIColor(red: 1.0, green: 2.0, blue: 3.0, alpha: 1.0))
queue.push(object: UIView(frame: CGRect(x: 1.0, y: 0.0, width: 22.0, height: 323.0)))
queue.pop() //1
**链表**[http://c.biancheng.net/view/3338.html](http://c.biancheng.net/view/3338.html)
class linkedListNode // 创建一个类 作为节点,节点分为两个部分,content:数据域和nextNode:指向下一个节点的指针域
{
var content: Int // 数据与
var nextNode: linkedListNode? // 指针域
init(_ content: Int) { // 节点初始化
self.content = content //数据域
self.nextNode = nil //指针域初始化为nil
}
}
class linkedList
{
var headerNode: linkedListNode? //头结点
var tailNode: linkedListNode? //尾节点
func appendToHeader(content: Int) { // 头尾空就 头尾相同都为nil
if headerNode == nil {
headerNode = linkedListNode(content)
tailNode = headerNode
}else{
let temporaryNode = linkedListNode(content) //头部位空就让头往后移,新的节点作为头,指向原来的头节点
temporaryNode.nextNode = headerNode
headerNode = temporaryNode
}
}
func appendToEnd(content: Int) {
if tailNode == nil {
tailNode = linkedListNode(content)
headerNode = tailNode
}else{
tailNode?.nextNode = linkedListNode(content) //尾节点不为nil,就指向下一个节点,下一个节点作为尾节点
tailNode = tailNode?.nextNode
}
}
}
** swift冒泡排序 **
** 闭包 **
[闭包参考资料1](https://www.jianshu.com/p/7043ffaac2f2)
[闭包参考资料2](https://zhuanlan.zhihu.com/p/92464947)
网友评论