zoukankan      html  css  js  c++  java
  • Swift基础(二)

    1、?和!

    • 在swift中,可选类型(?)其根源是一个枚举型,里面有None和Some两种类型。其实所谓的nil就是Optional.None, 非nil就是Optional.Some。
    • 可选类型分为有值和没值,如果可选类型的变量没值时对其强制解包,程序就会崩溃 。所以,强制解包是非常危险的。
    // ? 有值,没值(nil)
    // ! 强制解包
    var number : Int? = 8
    // 如果对没值(nil)的变量进行强制解包的情况下会造成崩溃
    var number1 = number!
    print(number1)
    
    // 可选绑定,不用强制解包(在不确定可选类型变量是否有值时使用)
    if var number2 = number{
        print(number2)
    }
    
    // 隐式解析可选类型(!):有值,没值(nil)
    // 如果!强制解析没值的变量,也会造成崩溃
    var intNumber:Int! = 10
    var intNumber1 = intNumber
    print(intNumber1)
    
    // 可选绑定
    if var intNumber2 = intNumber{
        print(intNumber2)
    }

    2、结构体

      Swift的结构体对比OC来说,可以添加初始化方法、可以遵守代理协议等。

    // MARK: - 结构体
    // 1.声明一个结构体
    struct Rect{
        // 声明结构体变量的属性(存储属性)
        var x:Float
        var y:Float
        var Float
        var height:Float
        // 声明结构体属性,要使用static
        static var description:String?
        // 声明一个计算属性(是用来专门计算结构体变量属性的setter方法和getter方法,其本身并没有存储功能)
        var centerX:Float{
            // setter方法
            set{
                x = newValue
            }
            // getter方法
            get{
                return x / 2
            }
        }
        var centerY:Float{
            get{
                return y / 2
            }
        }
        // 声明方法
        // 声明一个结构体变量方法(相当于OC中的实例方法)
        // 成员方法
        func frameInfor(){
            print("x:\(x),y:\(y),\(width),height:\(height)")
        }
        // 类方法在成员方法之前用static修饰
        static func infor(){
            print("这事结构体方法0")
        }
    }
    
    // 根据结构体去定义一个结构体变量
    var frame = Rect(x: 5, y: 5,  5, height: 5)
    print(frame)
    // 访问结构体变量中的属性
    // 注意:结构体变量的属性类型可以使用let去修饰,只不过访问的时候不能对其值进行修改
    frame.x = 10
    print(frame.x)
    // 访问结构体属性
    Rect.description = "我是结构体属性"
    print(Rect.description)
    // 访问计算属性
    frame.centerX = 200 // 这句话就相当于在调用centerX的setter方法
    frame.x = frame.centerX // 这句话就相当于在调用centerX的getter方法
    print(frame.x)
    frame.frameInfor()
    Rect.infor()

    3、类

    • 类是人们构建代码所用的一种通用且灵活的构造体。我们可以使用与结构体完全相同的语法规则来为类定义属性(常量、变量)和添加方法。
    • 我们通过关键字class来定义类,并在一对大括号中定义它们的具体内容:
    • class ClassName {
    • 类的内部细节
    • }
    // MARK: - 类(class)
    class Person{
        var name:String?
        var age:Int?
        // 构造初始化方式
        init(name:String,age:Int){
            self.name = name
            self.age = age
        }
        // 自定义初始化方法
        init(name:String){
            self.name = name
        }
        // 类属性
        static var introduce:String?
        // 计算属性,不能出现self
        var value:Int{
            set(a){
                age = a
            }
            get{
                return age!
            }
        }
        // 声明一个类方法
        // 1.在类方法前边加上static修饰(虽然是一个类方法,但是该方法在子类中不能进行重写)
        static func sayHi(){
            print(introduce)// 在类方法中只能使用类属性,不能使用对象属性
        }
        // 2.在类方法前边加上class修饰(可以在子类中重写)
        class func sayHello(){
            print(introduce)
        }
        // 声明一个实例(对象)方法
        func sayHei(){
            print("hello,我是实例方法")
        }
        
    }
    
    // 创建对象[要写初始化构造的方法]
    var per:Person = Person(name: "Boy", age: 21)
    print(per.name)
    // 访问类属性
    Person.introduce = "我是XXX"
    per.value = 22
    print(per.value)
    print(Person.introduce)
    // 访问类方法
    Person.sayHi()
    Person.sayHello()
    
    // 访问实例方法
    per.sayHei()
    
    // 定义一个子类Student,继承Person
    // 在Swift中不支持多继承
    class Student:Person {
        // 重写父类的方法
        override class func sayHello() {
            print("qweqwew")
        }
        // 重写父类中的实例方法
        override func sayHei() {
            print("我是子类的实例方法")
        }
        
    }
    // 初始化Student对象
    var student = Student(name: "张三", age: 54)
    // 重写的类方法
    Student.sayHello()
    // 对象方法
    student.sayHei()
    • 值类型:该类型的每个实例持有数据的副本,并且该副本对于每个实例来说是独一无二的一份,比如结构体(struct)、枚举(enum)、元组(tuple)都是值类型。
    • 引用类型:该类型的实例共享数据唯一的一份副本(在native层面说的话,就是该类型的每个实例都指向内存中的同一个地址),比如类(class)就是引用类型。
    // MARK: - 值类型和引用类型的区别
    
    struct animal {
        var name:String?
        var age:Int?
        init (name:String,age:Int){
            self.name = name
            self.age = age
        }
    }
    
    var dog = animal(name: "阿A", age: 3)
    
    var dog1 = dog
    dog1.name = "换换"
    print("dog = \(dog)")
    print("dog1 = \(dog1)")
    
    // 引用值类型
    class animal{
        var name:String?
        var age:Int?
        init(name:String,age:Int){
            self.name = name
            self.age = age
        }
    }
    
    var dog = animal(name: "啊c", age: 2)
    var dog1 = dog
    dog.name = "换换"
    print("dog = \(dog.name)")
    print("dog1 = \(dog1.name)")
    • 使用值类型的情形:
    • 使用==运算符比较实例数据的时候。
    • 你想单独复制一份实例数据的时候。
    • 当在多线程环境下操作数据的时候。
    • 使用引用类型(比如class)的情形:
    • 当使用===运算符判断两个对象是否引用同一个对象实例的时候。
    • 当上下文需要创建一个共享的、可变的对象时。

    4、协议

    • 协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必需的方法和属性。
    • 类,结构体或枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能。
    • 任意能够满足协议要求的类型被称为遵循(conform)这个协议。
    • @objc 修饰的协议,其中的方法可以声明成可选实现(使用optional修饰)。
    // MARK: - 协议(protocol)
    // 当Swift中声明协议的时候,协议里有可选方法需要使用@objc关键字修饰
    @objc protocol MarryDelegate{
        func cook() // 做饭
        func wash() // 洗衣服
        optional func hitDouDou() // 打豆豆.可选方法
    }
    protocol DivorceDelegate{
        func divisionProperty() // 分割财产
    }
    // 先写继承的类,然后再写要遵守的协议
    class Man:Person,MarryDelegate,DivorceDelegate {
        @objc func cook() {
            print("做饭")
        }
        @objc func wash() {
            print("洗衣服")
        }
        func divisionProperty() {
            print("分财产")
        }
    }
    
    var man:Man = Man(name: "ad", age: 23)
    man.cook()
    man.wash()
    
    man.divisionProperty()

    5、扩展

    • extension + 类名(结构体名字)可以对一个类和结构体扩展方法
    • extension可以多次对一个类进行扩展,也可以给一个类扩展协议方法
    // MARK: - 扩展(Extension)
    // 1.扩展协议中的相关方法
    extension Man {
        @objc func hitDouDou() {
            print("dsadasdas")
        }
    }
    man.hitDouDou()
    // 2.扩展还可以扩展类方法(给某一个类添加方法,类似于OC中的Category)以及对象方法
    extension Man{
        // 扩展一个对象方法
        func sing(){
            print("唱歌")
        }
        // 扩展一个类方法
        class func play() {
            print("")
        }
    }
    man.sing()
    Man.play()

    6、闭包

    • 闭包是自包含的函数代码块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的代码块(block)以及其他一些编程语言中的 匿名函数比较相似。
    • 闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift 会为您管理在捕获过程中涉及到的所有内存操作。
    // MARK: - 闭包
    // 求两个数的最大值
    /*
    在OC中使用Block实现
    int (^myBlock)(int num1, int num2) = ^int(int num1, int num2) {
        return num1 > num2 ? num1 : num2;
    }
    */
    // 使用闭包
    var myBlock : ((num1:Int,num2:Int)->Int)
    // 第一种使用方式
    myBlock = {
        (num1:Int, num2:Int) -> Int in
        return num1 > num2 ? num1 : num2
    }
    print(myBlock(num1: 3, num2: 6))
    // 第二种方式
    myBlock = {
        num1,num2 in
        return num1 > num2 ? num1 : num2
    }
    print(myBlock(num1: 7, num2: 6))
    // 第三种方式
    myBlock = {
        num1,num2 in
        num1 > num2 ? num1 : num2
    }
    print(myBlock(num1: 10, num2: 22))
    // 第四种方式
    myBlock = {
        $0 > $1 ? $0 : $1
    }
    print(myBlock(num1: 10, num2: 22))
    // 第五种方式
    myBlock = {
        (num1,num2)->Int in
        return num1 > num2 ? num1 : num2
    }
    print(myBlock(num1: 99, num2: 66))
    • 闭包传值:
        // 在第二个视图控制器创建返回按钮
        var block = {
            (str:String)-> Void in
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            // 创建返回按钮
            let button: UIButton = UIButton(frame: CGRectMake(10,100,50,50))
            button.addTarget(self, action: Selector("buttonAction"), forControlEvents: UIControlEvents.TouchUpInside)
            button.setTitle("返回", forState: UIControlState.Normal)
            button.backgroundColor = UIColor.cyanColor()
            self.view.addSubview(button)
    
            // Do any additional setup after loading the view.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        // 返回按钮实现
        func buttonAction() {
            // 闭包调用
            self.block("block返回值")
            self.navigationController?.popViewControllerAnimated(true)
        }
    
        // 在第一个视图控制器实现闭包
    class FirstViewController: UIViewController {
        var secondVC: SecondViewController! = SecondViewController()
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.grayColor()
            // 创建跳转按钮
            let button: UIButton = UIButton(frame: CGRectMake(10,100,50,50))
            button.addTarget(self, action: Selector("pushAction"), forControlEvents: UIControlEvents.TouchUpInside)
            button.setTitle("push", forState: UIControlState.Normal)
            button.backgroundColor = UIColor.cyanColor()
            self.view.addSubview(button)
            // Do any additional setup after loading the view.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        // push按钮方法实现
        func pushAction(){
            secondVC.view.backgroundColor = UIColor.orangeColor()
            // 闭包实现
            secondVC.block = {
                str in
                print(str)
            }
        
            self.navigationController?.pushViewController(secondVC, animated: true)
        }
  • 相关阅读:
    安装future包,django-crispy-forms
    django学习笔记(七)-----视图
    django学习笔记(六)-----模型
    django学习笔记(五)------path
    django学习笔记(四)---基本流程三(视图,模板基本使用)
    django学习笔记(三)--基本流程二---admin站点管理
    django学习笔记(二)基本流程一
    C#时间
    可空类型的DateTime转换成字符串
    asp.net mvc Razor一点小注意点
  • 原文地址:https://www.cnblogs.com/soley/p/5521369.html
Copyright © 2011-2022 走看看