Swift之基础知识

  • 出于对Swift3.0的学习,写下这篇基本语法的笔记。希望能帮助记忆 -0-
  • 这边提供Swift3.0中文教材,资源链接: https://pan.baidu.com/s/1c2GDBtI 密码: ea4i

一. 第一个应用程序

0. 小技巧:
> 'option + cmd + /': 增加文档注释
> 'color + 回车': 弹出颜色选择
> '图片名 + 回车': 图像视图
> '// MARK: - XXX': mark
> '// TODO: XXX'和'// FIXME: XXX': 临时标注(一般用后者) 1. 和OC的区别:
1.1 类和对象
OC: '[[UIView alloc] initWithXXX: ];'
Swift: 'UIView(XXX: )'
'UIView()' 1.2 类方法
OC: '[UIColor redColor]'
Swift: 'UIColor.red()'
2.0 : 'UIColor.redColor()' 1.3 访问当前对象属性,可以不使用'self'
建议都不用, 因为闭包(类似block)时需要使用'self' 1.4 没有';', 默认一行一句代码就不出错 1.5 枚举类型
OC: 'UIButtonTypeContactAdd'
Swift: '.contactAdd' 1.6 监听方法
OC: '@selector'
Swift: '#selector',有参数不需要加':'
2.0: 直接使用"",有参数需要加':'

二. 变量与常量

1.变量: 值能被修改, var修饰
常量: 值不能被修改, let修饰
2.自动推导: 变量/常量的类型会根据右侧的代码执行结果,推导对应的类型(option + click查看)
3.注意点:
> 在任何不同类型的数据之间, 不允许直接运算
> 不存在基本数据类型, 都是结构体
4.optional可选项(等价于:类型+?)
4.1 可以有值, 可以为nil不是任何数据类型,不能参与计算
4.2 计算要用'!'强制解包, 如果有nil, 则直接报错:unexpectedly found nil wghile unwrapping an Optional value
4.3 let的可选值没有默认值
var的可选值默认为nil
4.4 空合运算符( a ?? b )将对可选类型 a 进行空判断:如果a为nil,则执行b,否则执行a

三. 分支语句

1. if语句

1.1 注意点
1) 条件不需要'()'
2) 语句必须有'{}'

2. ??可选项的判断

2.1 空合运算符( a ?? b )将对可选类型 a 进行空判断:如果a为nil,则执行b,否则执行a
2.1 优先级比较低, 使用时最好加(), 例子如下:
let aName: String? = "老王"
print((aName ?? "") + "hello") // 打印:老王hello
print(aName ?? "" + "hello")// 打印:老王

3. if let & if var

let aDog: String? = "laowang"
let aAge: Int? = 10
// 3.1 判断对象的值是否为nil, {}内一定有值,可以直接使用不需要解包
// 3.2 if var连用, {}可以对值进行修改
if var name = aDog,
let age = aAge {
// 进入分支后,name和age一定有值,不需要解包
// name和age的作用于仅在{}中
name = "laoxiao"
print(name+String(age))
}else {
print("name或age有一个为nil")
}

3. guard let

// 3.1. guard let 和 if let刚好相反
// 3.2. guard let 守护一定有值,如果没有直接返回
let aDog: String? = "laowang"
let aAge: Int? = 10 guard let name = aDog,
let age = aAge else {
print("name或age为nil")
return
}
// 代码执行到这, name和age一定有值
// 通常判断是否有值之后, 会做具体的逻辑实现,通常代码多
// 如果用if let会多一层分支,guard是降低分支层次的办法
print(name+String(age))

4. switch

// 1.值可以是任何类型
// 2.作用域仅在 case 内部
// 3.不需要 break
// 4.如果要多值,使用','
// 5.每一个 case 都要有代码
let name = "nick" switch name {
case "nick":
let age = 18
print("one \(age)")
case "fil":
print("two")
case "Davi":
print("three")
case "": break //相当于有一行代码
case "tom","ningcol":
print("tomAndNingcol")
default:
print("other")
}

5. for循环

// 5.1 普通for循环: ..< 左闭右开; ...闭区间
for i in 0..<10 {
print(i)
}
// 5.2 使用 "_" 忽略不关心的值
for _ in 0..<5{
print("hello")
}
// 5.3 递增(步数为2)
for i in stride(from: 0, to: 12, by: 2) {
print(i)
}
// 5.4 递减
for i in stride(from: 12, to: 0, by: -2) {
print(i)
}
// 5.5 反序循环
let range = 0...10
for i in range.reversed(){
print(i)
} /***************************while循环*************************/
print("----while循环----")
var n = 2
while n < 100 {
n=n * 2
}
print(n) /***************************epeat-while循环*************************/
//它和 while 的区别是在判断循环条件之前,先执行一次循环的代码块。然后重复循环直到条件为 false
var m = 2
repeat {
m = m * 2
} while m < 100
print(m)

四. 字符串

  1. String 结构体,效率比对象高,一般推荐使用,支持遍历
  2. NSString 继承NSObject

1. 遍历

for c in str.characters {
print(c)
}

2. 长度

// 2.1 放回指定编码对应的字节数
// UTF8 的编码(0-4个), 每个汉字是3个字节
str.lengthOfBytes(using: .utf8)
// 2.2 返回字符个数(最常用)
str.character.count
// 2.3 使用NSString中转实现2.2
let ocStr = str as NSString
ocStr.length

3. 拼接

// 1."\(变量或常量)"
// 但是要注意可选项, 用??语句
let name:String? = "老王"
let age = 80
let location = "隔壁"
print(location + (name ?? "a") + String(age) + "岁")// "隔壁老王80岁"
print("\(location)\(name)\(age)岁")// "隔壁Optional("老王")80岁"
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
print("\(rect)")// "(0.0, 0.0, 100.0, 100.0)" // 2.格式化字符串
let h = 13
let m = 5
let s = 9
let timeStr = String(format: "%02d:%02d:%02d", arguments: [h,m,s])// "13:05:09"
let timeStr1 = String(format: "%02d:%02d:%02d", h,m,s)// "13:05:09"

4. 子串

一般使用NSString作为中转, 因为Swift取子串一直在优化, swift方法忽略

五. 集合

1. 数组

和OC一样, 但是没有'@'

1.1 定义和初始化

let array1 = ["zhangsan","lisi"]
let array2 = [1,2,3,4,5] var array3:[Int] // 定义一个数组(没有初始化)
array3 = [Int]() //初始化 //声明空数组,(必须初始化)
let array4 = [String]() // 等价上面两行代码 // Any任意对象
let array5:[Any] = ["zhangsan","lisi",20] var arr3 = [Double](repeating: 0.0, count: 3) //[0.0, 0.0, 0.0]
var arr4 = Array(repeating: 3.0, count: 3) //[3.0, 3.0, 3.0]

1.2 遍历

// 1.内容遍历
for name in array1{
print(name)
}
// 2.下标遍历
for i in 0..<array2.count{
print(array2[i])
}
// 3.enum block遍历, 同时遍历下标和内容
for e in array2.enumerated(){
print(e)
print("元组 \(e.offset) \(e.element)")
}
// 4.同时遍历下标和内容 2
for (n,s) in array2.enumerated(){
print("\(n) \(s)")
}
// 4.反序遍历
for a in array2.reversed(){
print(a)
}

1.3 增删改

// 增加
arr.append("haha") // 修改
arr[0] = "Tom" // 删除
arr.removeFirst()
arr.remove(at: 2) // 删除全部并保留空间
arr.removeAll(keepingCapacity: true)
print(arr.capacity) //数组容量 /************容量*************/
// 容量每次都会在原来基础上 * 2
print("初始容量 \(array3.capacity)")
for i in 0..<8{
array3.append(i)
print("\(array3),容量:\(array3.capacity)")
}

1.4 合并

// 直接相加
var arr = ["haha", "nihao", "hello"]
let arr1 = ["Evi","Tank"]
arr += arr1 // 注意点:类型必须一致
var arr1:[NSObject] = ["Evi" as NSObject,"Tank" as NSObject]
let arr2:[NSObject] = [1 as NSObject,2 as NSObject]
arr1 += arr2;

2. 字典

OC中使用{}, swift中使用[]

2.1 定义和初始化

let dict1 = ["name":"lisi","age":"18"]
// 不同类型必须指明为 any
var dict2:[String:Any] = ["name":"lisi","age":18] // 字典数组
let array = [
["name":"lisi","age":"18"],
["name":"wangwu","age":8]
]
let array1:[[String:Any]] = [
["name":"lisi","age":"18"],
["name":"wangwu","age":8]
]

2.2 增删改

// 增加
dict2["sex"] = "man"
// 修改(通过key来取值,key不存在就是新增)
dict2["name"] = "zhangsan"
// 删除(直接给key进行删除)
dict2.removeValue(forKey: "age")

2.3 遍历

for e in dict2{
//e 为元组
print("字典遍历:\(e) e.key:\(e.key) value:\(e.value)")
}
for (key,value) in dict2{
print("key:\(key), value:\(value)")
}

2.4 合并

var dict3:[String:Any] = ["name":"zhangsan","age":18,"sex":"man"]
let dict4:[String:Any] = ["name":"haha","height":50]
// 如果key存在修改 不存在会增加
for e in dict4{
dict3[e.key] = dict4[e.key]
}
print("合并dict:" + String(format: "%@", dict3))

六. 函数

1. 定义

// 格式: 函数名(形参列表) -> 返回值类型
func sum(x: Int ,y: Int) -> Int{
return x + y
} /**
1.外部参数是在形参前加一个名字
2.外部参赛不影响内部细节
3.外部参数让调用更加直观
*/
func sum(numX x: Int ,numY y: Int) -> Int{
return x + y
}
print(sum(numX: 30, numY: 40)) // 外部参数使用 "_" 会忽略形参
func sum(_ x: Int ,_ y: Int) -> Int{
return x + y
}
print(sum(40, 50)) // 不指定参数的值就为默认值
func sum1(x: Int = 1 ,y: Int = 2) -> Int{
return x + y
}
print(sum1())
print(sum1(x: 10, y: 10))
print(sum1(x: 20))
print(sum1(y: 20))

2. 闭包

2.1 定义

提前准备好的代码,在需要的时候执行,类似于oc中的block

/**
1.参数,返回值,实现代码都是写在 {} 中
2.必须以 "in" 关键字分隔定义和实现
3.格式: (形参列表 -> 返回值类型 in) 实现代码
*/
// 无返回值,有参数
let demo1 = { (x: Int) -> () in
print(x)
}
demo1(50) // 有返回值,有参数
let demo2 = {
(x: Int) -> (Int) in
return 40 + x
}
print(demo2(40))

2.2 实际应用

同OC中的 Block 一样

2.3 循环引用

  • 类似于oc一样,用weak var weakSelf = self // 注意只能用var来创建
  • 在闭包中加入[weak self] in,此时self为可选类型
  • 在闭包中加入[unknow self] in,不推荐,此时self不是可选类型,当self对象释放了在调用会出现奔溃。

2.4 尾随闭包

当一个函数的最后一个参数是闭包时,可以写成尾随闭包格式,了解就好。

// 尾随GCD闭包
DispatchQueue.global().async {
} // 普通GCD闭包
DispatchQueue.global().async(execute: {
})

Swift之基础知识的更多相关文章

  1. Swift入门基础知识

    var //代表变量,变量的值可以改变 let//代表常量类型不可改变 //声明常量heh类型Swift会自动根据你的值来自动判断该变量的类型也可以指定类型(个人感觉还是指定类型的比较好,可能会减少系 ...

  2. Swift Playgrounds for mac基础知识介绍

    Swift Playgrounds是一款适用于iPad和Mac的革命性应用程序,它使Swift学习变得互动而有趣.它不需要编码知识,因此非常适合刚开始的学生.使用Swift解决难题,以掌握基本知识.S ...

  3. iOS Swift基础知识代码

    推荐:Swift学习使用知识代码软件 //集合类型 数组 字典 func array1(){ var arr = [","dd"] //简单写法 var arr1 = [ ...

  4. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  5. iOS开发系列--C语言之基础知识

    概览 当前移动开发的趋势已经势不可挡,这个系列希望浅谈一下个人对IOS开发的一些见解,这个IOS系列计划从几个角度去说IOS开发: C语言 OC基础 IOS开发(iphone/ipad) Swift ...

  6. Runtime系列(一)-- 基础知识

    众所周知,Objective-C 是一种运行时语言.运行时怎么来体现的呢?比如一个对象的类型确定,或者对象的方法实现的绑定都是推迟到软件的运行时才能确定的.而运行时的诸多特性都是由Runtime 来实 ...

  7. openstack学习笔记(一)-openstack的基础知识

    一.OpenStack的基础知识 openstack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache2.0许可证(兼容GPLv3以及DFSG)授权的自由软件和 ...

  8. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  9. RabbitMQ基础知识

    RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...

随机推荐

  1. 简单3d RPG游戏 之 003 怪物AI

    游戏中,怪物会自动的往玩家所在地点走去,那需要创建一个C#脚本EnemyAI,包含两个功能: 1. 怪物旋转自己对准玩家 2. 怪物向前移动,追逐玩家 public class EnemyAI : M ...

  2. HDFS入门详解

    一. 前提和设计目标 1. 硬件错误是常态,因此需要冗余,这是深入到HDFS骨头里面去了 HDFS可能由成百上千的服务器所构成,每个服务器上存储着文件系统的部分数据.我们面对的现实是构成系统的组件数目 ...

  3. 编写你的第一个 Django 程序 第1部分

    原地址:http://django-chinese-docs.readthedocs.org/en/latest/intro/tutorial01.html 让我们通过例子来学习. 在本教程中,我们将 ...

  4. linux useradd添加用户

    useradd命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户. useradd -m -s /bin/bash -g 群组名 用户名 其中 -m:自动建立用户的登入目录. -s:指定用户 ...

  5. MyEclipse server窗口 Could not create the view: An unexpected exception was thrown 错误解决

    MyEclipse 打开后有时候莫名的在server窗口里抛出“Could not create the view: An unexpected exception was thrown”错误,解决办 ...

  6. N-Queens leetcode java

    题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...

  7. xcode 把cocos2d-x 以源码的形式包含进自己的项目适合, 性能分析问题的错误

    性能分析:出现如下错误: xcode profile  Variable has incomplete type   class “CC_DLL” 解决办法:在 xcode的Build Setting ...

  8. MyBatis的动态SQL操作--更新

    更新条件不确定,需要根据具体的情况生成sql语句. id是主键,一般不会去更新. 1.只更新name的值 update student set name = ? where id = ? 2.只更新s ...

  9. 分布式环境下的id生成方法

    分布式环境下的id生成方法   前几天研究数据库分表分库的问题,其中有一个关键的地方就是生成唯一键的问题,假如数据表有1亿条数据,而且还在不断的增加,这里我们就需要考虑到分表分库,假设我们采用Hash ...

  10. 25.allegro中模块复用[原创]

    一,Module reuse 1,打开原理图 ------------------- --------------------- ctrl+i过滤器 直选part ctrl+e 查看属性 查看: 是否 ...