swift的基本语法

一 swift中的三大特性(重载;继承;多态)

1 继承
—-> 1.1 举个例子来说明 : 创建一个Person类,并且再创建一个老师和学生类,同时老师和学生类都继承Person类
//创建一个类
class Person {
    var name = ""
    var age = 0
    //函数
    func runing() {
        print("人在跑步")
    }
    func study() {
        print("人在学习")
    }
}
—-> 1.2 学生类 :
//继承
class Student : Person {
    var sno : Int = 0
    //重写父类的方法
    override func study() {
     print("学生在敲代码")
    }

    override init() {
        super.init(name: "", age: 20)
    }
}
—-> 1.3 继承于Person的老师类
class Teacher: Person {
    //重写: 子类对父类的方法不满意,重写进行实现
    override func study() {
        print("老师在备课")
    }
}
—-> 1.4 创建各自的对象并且调用方法
//创建对象
let stu = Student()
stu.sno = 110
stu.name = "xaiofeng"
stu.age = 19

stu.runing()
stu.study()

let tea = Teacher()
tea.study()
2 重载
—-> 2.1 重载条件 : 1> 参数的类型不同 2> 参数的个数不同 (满足其一就可以)
class MathTool {
    func sum(num1 : Int, num2 : Int) ->Int {
        return num1 + num2
    }
    func sum(num1 : Int, num2 : Int, num3 : Int) ->Int {
        return num1 + num2 + num3
    }
    func sum(num1 : Int, num2 : Int, num3 : Int, num4 : Int) ->Int {
        return num1 + num2 + num3 + num4
    }
}

let mathTool = MathTool()
—-> 2.2 解读重载 : 在OC中我们是不能定义完全相同的方法名,即使参数不同也是不能定义的,但是在swift中可以,但是必须满足条件,并且满足其一就可以.由上面的代码我们可以看出: 参数类型相同;函数名称相同;仅仅不同的是参数的个数,这也是满足条件的.
3 多态
—-> 3.1 条件 : 1> 一定有继承 2> 一定有方法的重写 3> 一定是父类的指针指向子类的对象
func studentInNight(p : Person) {
    p.study()
}
studentInNight(stu)
studentInNight(tea)
4 补充(重写)
—-> 4.1 重写原因 : 子类对父类方法不满意,不能实现需求,子类通过重写方法来实现
—-> 4.2 重写的关键字 : override(必须要在函数的前面加上这个关键字)
—-> 4.3 特殊例子 : 创建一个不继承NSObject的类,设计构造方法,不需要加上override关键字
class Person {
    var name = ""
    var age = 0
    //函数
    func runing() {
        print("人在跑步")
    }
    func study() {
        print("人在学习")
    }
    //如果该类继承了NSObject,那么就必须在init前面加上override,因为init是父类的方法,这样做事属于重写
    init() {
    }
    //设计构造方法
    init(name : String, age : Int) {
        self.name = name
        self.age = age
    }
}

二 swift中的循环引用

1 Swift和OC一样,采用自动引用计数来管理内容
—-> 1.1 当有一个强引用指向某一个动向时,该对象的引用计数会自动+1
—-> 1.2 当该强引用消失时,引用计数会自动-1
—-> 1.3 当引用计数为0时,该对象会被销毁
—-> 1.4 在通常情况下,ARC是会自动帮助我们管理内存的
2 简单循环引用实例 : 直接创建一个Person类
class Person {
    var name = ""
    deinit {
        print("Person-----deinit")
    }
}
//创建类对应的对象
var person : Person? = Person()
—-> 2.1 用图解析 不打印原因

这里写图片描述

—-> 2.2 解决这种原因 : 让person指向空

这里写图片描述

2 实例 : Person有一本书,书有一个主人(owner)
//定义两个类
class Person {
    var name = ""
//    person有一本书
    var book : Book?
    deinit {
        print("Person-----deinit")
    }
}

class Book {
    var price = 0.0
    //书有一个主人
    var owner : Person?
    deinit {
        print("Book -- deinit")
    }
}
//创建类对应的对象
var person : Person? = Person()
var book : Book? = Book()
—-> 2.1 deinit并不会打印出结果
—-> 2.2 循环引用示意图:

这里写图片描述

—-> 2.3 此时你会发现计算将person = nil;book = nil都指向空,都不能解决问题,如下示意图

这里写图片描述

—-> 2.4 解决问题 : 让互相指向的其中一个指针变成弱指针就可以

这里写图片描述

—-> 2.5 需要写入的代码(满足其中一个就可以)
weak var book : Book?
unowned var book : Book = Book()

三 swift中的可选链

1 可选链的概念
—-> 1.1 它的可选性体现于请求或调用的目标当前可能为空(nil)
—-> 1.1.1 如果可选的目标有值,那么调用就会成功;
—-> 1.1.2 如果选择的目标为空(nil),则这种调用将返回空(nil)
—-> 1.2 多次调用被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。
2 可选链的使用
—-> 2.1 在可选类型后面放一个问号,可以定义一个可选链。
—-> 2.2 这一点很像在可选值后面放一个叹号来强制拆得其封包内的值
—–> 2.2.1 它们的主要的区别在于当可选值为空时可选链即刻失败
—–> 2.2.2 然而一般的强制解析将会引发运行时错误。因为可选链的结果可能为nil,可能有值.因此它的返回值是一个可选类型.
—–> 2.2.3 可以通过判断返回是否有值来判断是否调用成功 : 1> 有值,说明调用成功 2> 为nil,说明调用失败
3 例子 : 人有一只狗,狗有一个玩具(toy),玩具有一个价格(price)
class Person {
    var name = ""
    var dog : Dog?
}

class Dog {
    var name = ""
    var toy : Toy?
}

class Toy {
    var price  : Double = 0.0 {
        didSet {
            print(price)
        }
    }

    //玩具有一个具体行为
    func rotating() {
        print("玩具在转圈")
    }
}
//创建对象
let person : Person = Person()
person.name = "xiaofeng"

let dog : Dog = Dog()
dog.name = "bigYellowDog"

let toy : Toy = Toy()
toy.price = 1.0

//让对象之间产生关系
person.dog = dog
dog.toy = toy
—-> 3.1 需求一 : 给玩具赋值一个新值
第一种方式 :
person.dog!.toy!.price = 50.0
解析一 : 该方法也是可以赋值的,但是比较危险,因为并不能确定dog!和toy!一定有值,如果强制解包,返回的是nil,就会造成程序崩溃
第二种方式 : (推荐使用可选链–>比较安全)
person.dog?.toy?.price = 50.0
解析二 : 1.每一个可选进行判断,判断是否有值,如果有其中一个没有值,那么整个表达式返回一个nil 2.如果所有的可选类型都有值,那么整个表达式返回对应的类型,就可以给类型进行赋值
3.2 需求二 : 取出狗对象玩具的价格
第一种方法 :
let price = person.dog!.toy!.price
解析一 : 该方法不安全,很有可能什么都去不到,返回一个nil,程序会崩溃
第二种方式 : (推荐使用可选链–>比较安全)
let price1 = person.dog?.toy?.price
print(price1)
解析二 : 1.判断所有的可选类型是否有值,如果有其中一个没有值,那么整个可选链返回一个nil 2.如果可选类型都有值,那么返回一个具体的值
3.3 需求三 : 调用方法
第一种 : (也是可以实现的,但是比较麻烦)
person.dog!.toy!.rotating()
if let dog = person.dog {
    if let toy = dog.toy {
        toy.rotating()
    }
}
第二种 : 一句代码搞定
person.dog?.toy?.rotating()
解析二 : 1.如果可选类型中有一个没有值,那么该方法就不会执行 2.反之,如果可选类型都有值,那么就会执行该方法

四 协议

1 协议的格式 : 协议的定义方式与类,结构体,枚举的定义都非常相似
protocol SomeProtocol {
    // 协议方法
}
2 遵守协议的格式
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    // 类的内容
    // 实现协议中的方法
}
3 协议的具体代码
—-> 3.1 定义协议
//定义协议
protocol CrazySportProtocol {
    func jumping()
    func jumpingSan()
}
—-> 3.2 协议之间的继承关系
//协议之间的继承
protocol SportProtool : CrazySportProtocol {
    func playBasketball()
    func playFootball()
}
—-> 3.3 准守协议和实现协议中的方法(默认遵守了协议,就必须实现协议中的方法)
//创建类遵守协议
class Person : SportProtool {
    //遵守了协议就必须实现协议中的方法
    func jumping() {
        print("蹦极")
    }
    func jumpingSan() {
        print("跳伞")
    }
    func playBasketball() {
        print("打篮球")
    }
    func playFootball() {
        print("踢足球")
    }
}
—-> 3.4 创建对象调用方法
//创建对象调用方法
var person = Person()
person.jumpingSan()
person.jumping()
person.playBasketball()
person.playFootball()
—-> 3.5 代理在协议中的实现
//定义协议
protocol BuyTicketDelegate : class {
    func buyTicketing()
}

//创建类
class Person {
    var name = ""
    //设置代理
    weak var delegate : BuyTicketDelegate?
    func goToBeiJing() {
        //使用代理调用对应的方法
//        delegate?.buyTicketing()
        print("坐火车去北京")
    }
}

//定义一个类,并且遵守协议
class YellowCattle : BuyTicketDelegate {
    //将人设置里面的属性
    var vipPerson : Person?
    //实现协议中的方法
    func buyTicketing() {
        print("黄牛帮你买了一张票")
    }
}

//创建对象
let person = Person()
person.name = "xiaofeng"

//创建黄牛对象
let huangniu = YellowCattle()
huangniu.vipPerson = person

//将黄牛设置为代理
person.delegate = huangniu
person.goToBeiJing()
—-> 3.6 协议方法的可选择性(在swift中是没有协议可选择实现的,但是我们可以通过oc的方法来达到可选择实现的目的)
//将上objc和optional就代表了可以选择的实现
@objc
protocol SportsProtocol {
   optional func jumping()
   optional func jumpingSan()
}

class Person1 : SportsProtocol {
    @objc func jumping() {
        print("蹦极")
    }
}
let p = Person1()
p.jumping()

五 闭包

1 闭包简介
—-> 1.1 闭包和OC中的block非常相似
—-> —–OC中的block是匿名的函数
—–>—–Swift中的闭包是一个特殊的函数
—–>—–block和闭包都经常用于回调
2 block的使用
—-> 2.1 block的用法回顾
定义网络请求类 :
@interface HttpTool : NSObject
- (void)loadRequest:(void (^)())callBackBlock;
@end

@implementation HttpTool
- (void)loadRequest:(void (^)())callBackBlock
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"加载网络数据:%@", [NSThread currentThread]);

        dispatch_async(dispatch_get_main_queue(), ^{
            callBackBlock();
        });
    });
}
@end
进行网络请求,请求到数据后利用block进行回调
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.httpTool loadRequest:^{
        NSLog(@"主线程中,将数据回调.%@", [NSThread currentThread]);
    }];
}
block写法总结:
block的写法:
    类型:
    返回值(^block的名称)(block的参数)

    值:
    ^(参数列表) {
        // 执行的代码
    };
3 闭包代替block使用
定义网络请求的类
class HttpTool: NSObject {
    func loadRequest(callBack : ()->()){
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
            print("加载数据", [NSThread.currentThread()])

             dispatch_async(dispatch_get_main_queue(), { () -> Void in
                callBack()
             })
        }
    }
}
进行网络请求,请求到数据后利用闭包进行回调
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        // 网络请求
        httpTool.loadRequest ({ () -> () in
            print("回到主线程", NSThread.currentThread());
        })
    }
闭包写法总结:
闭包的写法:
    类型:(形参列表)->(返回值)
    技巧:初学者定义闭包类型,直接写()->().再填充参数和返回值

    值:
    {
        (形参) -> 返回值类型 in
        // 执行代码
    }
4 闭包的简写
—-> 4.1 如果闭包没有参数,没有返回值.in和in之前的内容可以省略
httpTool.loadRequest({
        print("回到主线程", NSThread.currentThread());
    })
—-> 4.2 尾随闭包写法:如果闭包是函数的最后一个参数,则可以将闭包写在()后面;如果函数只有一个参数,并且这个参数是闭包,那么()可以不写
httpTool.loadRequest() {
        print("回到主线程", NSThread.currentThread());
    }
// 开发中建议该写法
httpTool.loadRequest {
        print("回到主线程", NSThread.currentThread());
    }

六 懒加载

1 OC中有懒加载,而在swift中也存在懒加载.苹果希望我们对所有的对象只有在使用的时候才真在的加到内存中,这样能大大的减少了内存的消耗.
2 懒加载格式
lazy var 变量: 类型 = { 创建变量代码 }()
3 具体实例
—-> 3.1 懒加载写法一:(不推荐)
lazy var names : [String] = {
        return ["xiaofeng", "it", "nb"]
    }()

    lazy var btn : UIButton = {
        let tempBtn = UIButton()
        tempBtn.setTitle("按钮", forState: .Normal)

        return tempBtn
    }()
—-> 3.2 懒加载写法二 : (推荐)
lazy var button : UIButton = UIButton()

七 访问权限(下面只介绍概念)

1 private : 只能在当前文件中访问,不能在其他文件中访问
2 internal : 内部的,修饰整个项目,在整个项目中都可以进行访问,并且默认情况下修饰就是internal
3 public : 是可以跨框架访问

八 异常处理

1 try : 手动处理异常,并且获取在调用方法过程中到底产生了怎么样的异常
2 try? : 自己不处理异常,让系统帮助我们处理

系统如何处理:

—-> 2.1 如果该方法产生了异常,那么系统会将该方法的返回值为nil
—-> 2.2 如果该方法没有产生异常,那么系统会返回对应的类型结果
3 try! : 告诉系统这个方法不会产生异常 –> 注意:如果该方法产生了异常,那么程序会崩溃(不推荐)

九 oc和swift之间混编(给上具体步骤,这里就不简要说明了)

1 swift中调用OC代码
—-> 1.1 创建一个swift文件
—-> 1.2 在swift文件中创建一个oc类(点击don’t bridge)
—-> 1.3 创建一个桥接文件(仅仅是一个头文件)
—-> 1.4 配置 点击工程文件–> Bulid Setting –>brid –>双击objc填入bridge的文件路径
2 OC中调用swift代码
—-> 2.1 创建一个OC项目(标题不能写”_”,或者其他符号,使用全英文)
—-> 2.2 创建一个swift文件(点击don’t bridge)
—-> 2.3 导入一个头文件(项目名称 -swift.h)
—-> 2.4 swift都需要使用public修饰(方法/属性)

十 总结

1 swift语法基本已经介绍的差不多了,其中还有不足,一时间没有想到,希望看到我博客的人给点意见,让我知道还有那些没有介绍.明天给大家带来一个小小的demo.(纯swift代码实现)
2 最后大家如果觉得我写大博客还行,麻烦大家给点意见,好的坏的我都接受,麻烦大家关注我的官方博客,谢谢!!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值