关键字inout
这个例子是在playground下写的
// 声明2个变量
var x = 3
var y = 5
// 声明一个函数,函数的形参接收2个inout关键字标识的变量,可以理解是2个地址
func demo(inout X x:Int ,inout Y y:Int){
// 打印改变前的值,3,5
print(x,y)
// 赋值
x = y
// 打印改变后的值,5,5
print(x,y)
}
// 调用方法 传入2个结构体变量的地址
demo(X: &x, Y: &y)
// 打印在函数外边的2个结构体变量 5 5
print(x,y)
inout这个形参接收的相当于接收的是结构体变量的地址,所以根据地址在函数内部改变的值,在外部也会发生变化
函数的类型
举例:
func demo3(){
print("呵呵");
}
let d = demo3
上面这个类型函数的类型就是() -> ()
func demo1( let name name : String ,let age:Int){
print("\(name)\(age)")
}
上面这个类型函数的类型就是(String, Int) -> ()
函数的形参类型是函数类型,例:
func demo4(let test:()->()){
test()
}
形参test的类型为() -> ()
的函数类型,能够接收一个 形参返回值都为空得函数
函数的返回值类型是函数类型,例:
// 定义一个函数 这个函数的返回值是一个以String类型为形参,无返回值的函数.
func demo5()->((String)->()){
// 定义一个 形参String无返回值的函数
func test(let str :String){
print(str);
}
return test
}
// 定义一个函数变量来接收函数,是一个接收字符串形参无返回值的函数
var t = demo5()
调用
t("IOS")
返回值是一个String -> ()
类型的函数
枚举:rawValue
可以获取枚举的原始值用法,枚举类型.枚举值.rawValue
枚举:init(rawValue:)
可以根据原始值用来找到对应的枚举如:枚举类型(rawValue:3)
延迟加载 :lazy
例子:
class Dog: Animal {
var name:String?
var age:Int!
let color:String = "棕色"
lazy var id:Int = Int()
convenience init(name:String, age:Int){
self.init()
self.name = name;
self.age = age;
}
override func run() {
super.run()
print("狗跑")
}
}
lazy var id:Int = Int()
, lazy所标记的属性只有在第一次调用的时候才会计算初始值
计算属性
可以通过变量的其他属性经过计算获取到值,而本身当赋值的时候也不会储存而是拆开赋值给其他属性
struct Square {
var size :CGSize {
// get 是简洁 getter 方法,可以.语法访问.
get{
return CGSize(width: self.long, height: self.wide)
}
// set 是简洁 setter 方法,如果括号中不定义参数名的话可以使用newValue这个参数来获取值.
set(newSize){
self.long = newSize.width
self.wide = newSize.height
}
}
var long:CGFloat = 0;
var wide:CGFloat = 0;
}
属性监视器
属性监视器willSet
和didSet
可以通过新旧值的变化来进行一些判断,和需求实现.
实例:
struct Square {
var size :CGSize {
// get 是简洁 getter 方法,可以.语法访问.
get{
return CGSize(width: self.long, height: self.wide)
}
// set 是简洁 setter 方法,如果括号中不定义参数名的话可以使用newValue这个参数来获取值.
set(newSize){
self.long = newSize.width
self.wide = newSize.height
}
}
var long:CGFloat = 0{
// 在willset 也可以willset( ) 指定新值的变量名
willSet{
if(newValue < self.long){
print("减少了\(newValue - self.long )")
}
}
// 在didSet 也可以didSet( ) 指定旧值的变量名
didSet{
if(oldValue < self.long){
print("增加了\(self.long - oldValue)")
}
}
}
var wide:CGFloat = 0;
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var sq = Square();
sq.long = 30;
sq.wide = 20 ;
print(sq.size)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
打印的结果
增加了30.0
(30.0, 20.0)
注意的是:属性监视器只有在属性变化时才会调用不会去判断这个值是否相等.初始化的时候不会调用.
静态量,与类属性 static 与 class
static
静态变量 静态常量声明的关键字,可以写在类中,也可以写在结构体中,作用域为当前类,可以直接通过结构体名称+.语法使用,也可以用类名+.语法使用,亦或者通过类属性调用.
class
类属性关键字,格式: class var demo:Int{ ... }
在括弧中,可以使用在相同文件下的结构体名称调用静态属性来使用.
例子:
// 结构体中有一个静态变量
struct Type {
static var type:Int = 0;
}
class Test: NSObject {
// 类属性 指定set get,调用结构体中的静态值
class var t:Int {
set{
Type.type = newValue;
}
get{
return Type.type;
}
}
}
使用代码
Type.type = 3;
print(Type.type)
Test.t = 5;
print(Type.type);
print(Test.t)
输出结果:3 5 5
函数的外部参数名与内部参数名
func demo( name : String,age:Int ){
}
以上这段代码,name
是一个内部参数名,而age即是内部参数名也是外部参数名,在函数中第一个形参的外部名称是省略的当然,我们可以加上一个外部参数名,并且改写第二个参数的内部参数名如下:
func demo( name s1 : String,age s2 :Int ){
}
类方法,静态方法
与OC一样,swift也提供了类方法的实现,并且在结构体和枚举上也实现了静态方法(类型方法)的调用.
类方法声明在func
前写上class
,而类型方法前面写上static
.
脚本属性:subscript
附属脚本允许你通过在实例后⾯面的⽅方括号中传⼊入⼀一个或者多个的索引值来对实例进⾏行访问和赋值
subscript(x:CGFloat)->CGFloat{
return x * self.long;
}
防止重写的关键字final
在对象方法,类方法,属性,以及脚本属性前面如果加上了final
他得子类就不可以重写父类的方法,属性.
弱引用的关键字weak
在属性前面如果加上了weak
这个属性所指向的堆内存就是一个弱引用
弱引用的关键字unowned
在属性前面如果加上了unowned
这个属性所指向的堆内存就是一个无主引⽤,无主引用是非可选类型,不可以赋值为nil,而如果无主引用所指向的堆内存已经被释放了,还去访问和调用,则程序会崩溃.
也可以用关键字unowned
在构建定义占有列表 [unowned self] in
自动构造器的继承
有2种方法自动继承全部的父类构造器:1,子类中没有一个构造器将自动继承父类所有的构造器. 2,子类重载了父类的所有构造器(都重载了,当然继承了,并且可以在添加新的)
析构函数
一个对象从内存中释放之前所执行的函数,注意的是没有()
deinit {
print("被释放了")
}
类型嵌套
swift 支持 内部类,内部枚举,结构体等...
class Dog: NSObject {
// 内部类 名字
class Name: NSObject {
//内部类属性
var surname:NSString!
var name:NSString!
}
var name : Name = Name();
}