可选类型
//
在
swift
中
,
可选类型
?
其根源是一个枚举型
,
里面有
None
和
Some
两种类型
.
其实所谓的
nil
就是
Optional.None,
非
nil
就是
Optional.Some
//
定义一个可选类型
,
表示这个变量可以为
nil
var
intNumber :
Int
? = 100
//
打印
打印出来是个
Optional
类型的值
print
(
intNumber
)
//
如果
要取到值
必须对可选类型
强制解包
!
print
(
intNumber
!)
//
可选类型分为有值和没值
(nil) ,
如果可选类型的变量值为
nil(
没值
)
时对其
强制解包
,
程序会崩溃
//
如果不确定可选类型是否有值时
,
用可选绑定
,
不需要对可选类型解包
if
var
intNewNumber =
intNumber
{
print
(intNewNumber)
}
else
{
print
(
"error"
)
}
结构体
/*
Swift
的结构体对比
OC
来说
,
可以添加初始化方法
,
可以遵守代理协议等
*/
//
使用
struct
定义一个结构体
//
格式
: struct
结构体名字
{
结构体实现
}
struct
Frame {
//
存储属性
:
负责存储值的属性
var
x :
Float
var
y :
Float
var
width :
Float
var
height :
Float
//
计算属性
:
负责将存储属性进行运算获得的值的属性
//get
方法
:
在属性类型后面添加
{}
使用
get
关键字声明和实现
get
方法
//set
方法
:
同上
var
centerX :
Float
{
//set
方法
不可以单独实现
,
必须搭配着
get
方法
set
{
}
//get
方法
可以单独实现
get
{
return
x
+
width
/2
}
}
var
centerY :
Float
{
get
{
return
y
+
height
/2
}
}
//
结构体属性
static
var
myStruct =
"
结构体属性
,
只能通过结构体调用
"
//
结构体中可以声明和实现函数
func
sayHi() {
print
(
"
函数
"
)
}
//init
方法
init
(x newX :
Float
, y newY :
Float
, width newWidth :
Float
, height newHeight :
Float
) {
x
= newX
y
= newY
width
= newWidth
height
= newWidth
}
//
结构体的类方法
//
结构体的类方法中只能调用结构体属性
static
func
sayMy() {
print
(
self
.myStruct)
}
}
//
属性作用
:
//
声明
_
实例变量
//
声明和实现
set
方法
//
声明和实现
get
方法
//
结构体调用
Frame
.
sayMy
()
print
(
Frame
.myStruct)
//
创建一个对象的方式
//
方式
1: init
var
frame1 :
Frame
=
Frame
.
init
(x: 10, y: 10, width: 100, height: 100)
//
方式
2:
自带的构造方法
var
frame2 :
Frame
=
Frame
(x: 10, y: 10, width: 100, height: 100)
//
对象调用属性
print
(
frame1
.
centerX
)
//
对象调用方法
frame1
.
sayHi
()
类 class
/*
类是人么构建代码所用的一种通用且灵活的构造体
.
我们可以使用与结构体完全相同的语法规则来为类定义属性
(
常量
,
变量
)
和
添加方法
*/
class
Person {
//
类的属性
要设置
初值
或者
可选类型
var
name :
String
=
""
var
gender :
String
?
var
age :
Int
= 20
//
计算属性
var
width :
Float
{
get
{
return
100
}
set
{
//set
方法中的
newValue
表示新的值
self
.
width
= newValue
}
}
//static
修饰的是类属性
//
类属性只能由类属性调用
static
var
hobby :
String
=
"John"
//
普通函数里面不能调用类属性
static
func
sayWao(){
print
(
self
.hobby)
}
func
sayHello() {
print
(
"Hello
\
(
self
.
width
)"
)
}
init
(name newName :
String
, gender newGender :
String
, age newAge :
Int
) {
name
= newName
gender
= newGender
age
= newAge
}
}
var
person :
Person
=
Person
.
init
(name:
"Depp"
, gender:
"
男
"
, age: 42)
person
.
sayHello
()
Person
.
sayWao
()
//
继承
class
Classes {
var
student :
String
=
""
var
number :
Int
?
//
var
sum :
Int
{
set
{
number
= newValue
}
get
{
return
20
}
}
func
read() {
print
(
"
早读
"
)
}
static
var
master :
String
=
"A"
static
func
who() {
print
(
self
.master)
}
init
(student newStudent :
String
, number newNumber :
Int
) {
student
= newStudent
number
= newNumber
}
}
var
classesOne :
Classes
=
Classes
.
init
(student:
"
卡特
"
, number: 5223)
print
(
classesOne
.
student
)
classesOne
.
read
()
Classes
.
who
()
//
继承
class
student :
Person
{
var
number :
Int
?
//
重写父类方法
:
前面需要添加
override
修饰
override
func
sayHello() {
// super.sayHello()
}
//
重写父类的
init
函数
override
init
(name newName:
String
, gender newGender:
String
, age newAge:
Int
) {
super
.
init
(name: newName, gender: newGender, age: newAge)
}
init
(number newNumber :
Int
) {
super
.
init
(name:
"lll"
, gender:
"nnn"
, age: 1)
number
= newNumber
}
}
协议
/*
协议定义了一个蓝图
,
规定了用来实现某一特定工作
或者
功能所必需的方法和属性
类
,
结构体或枚举类型都可以遵循协议
,
并提供具体实现来完成协议定义的方法和功能
*/
//
声明一个协议
//protocl
声明的协议
是
Swift
的协议
,
所有的方法都必须实现
protocol
myDelegata{
//
一个协议方法
func
test()
//
使用
mutating
修饰的函数
可以在结构体里面修改结构体的属性
//
协议里面使用
mutating
修饰的函数
,
在遵守协议的时候
可以不使用
mutating
修饰
,
在类里没有影响
,
在结构体力面
,
就不能修改属性的值了
.
但是
如果实现协议里没有
mutating
修饰的函数的时候
,
却用了
mutating
修饰
,
结果是在结构体重新声明了一个函数
,
此函数和协议无关系
mutating
func
change()
}
//
使用
@objc
修饰的协议
表示
oc
的协议
-> @objc
修饰的协议
不可用在结构体里面遵守
//
使用
@objc
修饰的协议里可以声明可选实现的函数
(
用
optional
修饰函数
)
//
在实现这个函数的时候
,
在函数前面要加
@objc
修饰
@objc
protocol
newDelegate{
optional
func
newTest()
func
newChange()
}
//
class
Teacher:
Person
,
myDelegata
,
newDelegate
{
func
test() {
print
(
"233333"
)
}
//
协议里使用
mutating
修饰的函数
,
在类里面就是一个普通的函数
func
change() {
}
//
协议里
optional
修饰的可以选择实现
// @objc func newTest(){
// }
@objc
func
newChange() {
}
}
let
teacher :
Teacher
=
Teacher
(name:
"a"
, gender:
"b"
, age: 233)
teacher
.
test
()
struct
myStruct:
myDelegata
{
var
name :
Int
?
func
test() {
print
(
"3444444"
)
}
mutating
func
change() {
name
= 100
}
}
扩展 extension
/*
extension +
类名
表示要给这个类做扩展
extension
只可以扩展函数
,
不能扩展属性
extension
可以给一个类扩展代理协议
*/
extension
Person
:
myDelegata
{
func
test() {
}
func
change() {
}
func
sayNoNoNo(){
}
}
// extension
可以给结构体扩展新的协议
extension
Frame
:
myDelegata
{
func
test() {
}
func
change() {
}
}
闭包
/*
闭包是自包含的函数代码块
,
可以在代码中被传递和使用
.
Swift
中的闭包与
C
和
OC
中的代码块
block
以及其他一些编程语言中的
匿名函数比较相似
闭包可以捕获和存储其所在上下文中任意常量和变量的引用
.
这就是所谓的闭合并包裹着这些常量和变量
,
俗称闭包
.Swift
会为管理捕获过程中的内存操作
*/
var
myBlock : ((a :
Int
, b :
Int
) ->
Int
)
// 1
myBlock
= {
(a :
Int
, b :
Int
) ->
Int
in
return
a > b ? a : b
}
// 2
省略参数和返回值类型
myBlock
= {
a, b
in
return
a > b ? a : b
}
// 3
省略参数和返回值类型
,
省略
return
关键字
myBlock
= {
a, b
in
a > b ? a : b
}
// 4
使用
$
符号表示
取第几个参数
myBlock
= {
$0 > $1 ? $0 : $1
}
// 5
官方推荐的格式
myBlock
= {
(a, b) ->
Int
in
return
a > b ? a : b
}
值类型与引用类型
值类型:
该类型的每个实例持有数据的副本, 并且该副本对于每个实例来说是对无二的一份, 比如结构体(struct), 枚举(enum), 元组(tuple)都是值类型
引用类型:
该类型的实例共享数据唯一的一份副本 (在native层面说的话, 就是该类型的每个实例都指向内存中的同一个地址), 比如(类)就是引用类型.
使用值类型的情形:
使用==运算符比较实例数据的时候;
想单独复制一份实例数据的时候
当在多线程环境下操作数据的时候.
使用引用类型(比如class)的情况:
当使用==运算符判断两个对象是否引用同一个对象实例的时候.
当上下文需要创建一个共享, 可变的对象时.
/*
存储属性就是类
或
结构体定义的变量
(
或
常量
).
存储属性可以是变量存储属性
(
用关键字
var
定义
),
也可以是常量存储属性
(
用关键字
let
定义
)
除存储属性外
,
类
,
结构体和枚举
可以定义计算属性
.
计算属性不直接存储值
,
而是提供一个
getter
和
一个可选
的
setter,
来间接获取和设置其他属性或变量的值
*/