zoukankan      html  css  js  c++  java
  • Swift2

    Senior进阶
    Swift(二)

    一、可选类型(?)
    在swift中,可选类型(?)其根源是一个枚举型,里面有None和Some两种类型。其实所谓的nil就是Optional.None,非nil就是Optional.Some。
    //定义一个Int类型的可选类型变量
    var intNumber:Int? = 8
    //把这个类型类型的变量赋值给另一个可选类型的变量
    var intNumberOne:Int? = intNumber
    print(intNumberOne)

    //打印出来以后是一个Optional类型的值,如果要取到8,必须对可选类型强制解包

    var intNumberTwo:Int? = intNumber!

    print(intNumberTwo)


    //可选绑定

    //可选类型分为幼稚和没值,如果可选类型的变量没值时对其强制解包,程序就会崩溃。所以解包是飞航危险的

    varNumber:Int?
    //!表示强制解包

    //var NumberOne = Number!
    //print(intNumberOne)

    //如果不确定可选类型是否有值时,用可选绑定,不需要对可选类型强制解包

    if var intNumberTwo = Number {
    print(intNumberTwo)
    }


    //隐式解析可选类型(!)
    隐式解析可选类型和可选类型一样,都是有值和没值(nil)两种结果,区别是赋值时,隐式解析可选类型不需要强制解包。

    //!隐式解析可选类型:有值,没值(nil)

    var intNum:Int! = 10
    //如果隐式解析可选类型的变量没值,程序一样会崩溃

    //var intNumberOne = intNum
    //print(intNumOne)


    //可选绑定

    if var intNumTwo = intNum {
    print(intNumTwo)
    }

    一、结构体

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


    struct point{ struct size {

    var x = 0 var width = 0
    var y = 0 var height = 0
    } }

    声明一个结构体的格式:struct +结构体的名字 + {
    声明成员变量等
    }


    结构体的成员方法和类方法

    struct Rect {
    var point:(a:int,b:int) = (0,0)
    var size:(w:int,h:int) = (0,0)

    //成员方法
    func getSize(){
    print(size)
    }
    //结构体的类方法:成员方法前用static修饰

    static func sayHello() {
    print(“heiilo”)

    }

    }//结构体的构造方法

    var rect2:Rect = Rect(point:(10,10),size:(50,50))

    //结构体有自带的构造方法

    var rect:Rect = Rect(point:(10,10),size(50,50))

    //调用Rect结构体的成员方法
    rect.getSize()
    //结构体的类方法用类名调用
    Rect.sayHello()

    二、类
    类是人们构建代码所用的一种统一且灵活的构造体。我们可以使用与结构体完全相同的语法规则来为类定义属性(常量、变量)和添加方法。
    我们通过关键字class来定义类,并在一堆大括号中定义他们的具体内容:
    class ClassName {
    类的内部细节
    }
    值类型
    该类型的每个实例持有数据的副本,并且该副本对于每一个实例来说是独一无二的一份,比如结构体(struct)、枚举(enum)、元组(tuple)都是值类型


    //值类型
    //值类型实例
    stuck StructObject {
    var data:int = -1
    //创建一个StructObject结构体变量

    var sol = StructObject()

    //将sol变量的值给s02,其实是一个拷贝的过程

    var s02 = so1

    //so1的数据改变了,但是so2
    的并没有改变

    so1.data = 42

    print(“(so1.data),(so2.data)”)//prints”42,-1”
    }
    引用类型

    该类型的实例共享数据唯一的一份副本(在native层面说的话,就是该类型的每一个实例都指向内存中的痛一个地址),比如类(class)就是引用类型


    //引用类型事例

    class ClassObject {
    var data:Int = -1
    //创建一个ClassObject结构体变量
    var co1 = ClassObject()

    //将co1变量的值赋值给co2,其实是一个引用的过程

    var co2 = co1

    //co1的数据改变了,但是co2也发生了改变

    co1.data = 42
    print(“(co1.data),(co2.data)”)//prints”42,42”

    }

    值类型与引用类型使用情形

    使用值类型的情形:
    使用==运算符比较实例数据的时候。
    你想单独赋值一份实例数据的时候。
    当在读线程环境下操作数据的时候。
    使用引用类型(比如class)的情形:
    当使用==运算符判断两个对象是否引用同一个对象实例的时候
    当上下文需要创建一个共享的、可变的对象时。

    类的定义和构造方法

    定义一个Person
    class Person {

    var Person {
    var name:String?
    var age:Int?
    //类的构造方法

    init(name:Srting,age:Int){
    self.name = name
    self.age = age
    }
    }

    计算属性与存储属性
    存储属性就是类或结构体里定义的变量(或常量)。存储属性可以是变量存储属性(用关键字 var定义),也可以是常量存储属性(用关键字let定义)

    除存储属性外、结构体和枚举可以定义计算属性。计算属性不直接存储值,而是提供一个getter好一个可选的setter,来简介获取和设置其他属性或变量的值。

    1.定义一个Person类

    class Person {
    //声明存储属性
    var name :String?

    //声明计算属性

    var number:int {
    get{return 10}
    set { print(newValue){
    }
    //初始化构造方法
    init(name:String,age:int) {
    self.name = name}
    }


    创建实例对象

    var Lize = Person(name:”xiaoze”,age:20)
    访问对象的name属性

    print(Lize.name)

    类属性和类方法

    定义一个Student类
    class Student {
    //声明类属性

    static var introduce:String?

    //声明类方法(使用static和class都可以修饰类方法,区别在于:class修饰的类方法可以被子类重写)

    static fun sayHi(){print(introduce)}
    class func saySaWaDika(){print(introduce)}
    }

    //声明一个协议

    @objc修饰的协议,其中额方法可以声明称可选实现(使用optional修饰)

    声明一个带有可选函数的协议

    @objc protocol SayHelloDelegate {
    optional fun satHello ()
    }

    声明一个所有函数都必须实现的协议

    protocol DescriptionDelegate {
    func description()->String
    static fun aClassMethod()->String//表示声明了一个类方法
    }

    //类遵守协议,直接写在本类名后面的冒号的后面,使用“,”号分隔

    class ErShiXiong:NSObject,SayHelloDelegate,
    DescriptionDelegate {
    //必须实现的协议方法,就必须实现,否则会报错
    func text(){
    }
    //可选协议方法,会报警告,可以添加@objc,或者继承NSObject

    @objc fund test(){
    }
    }

    四、扩展(Extension)

    extension + 类型 (结构体名字)可以对一个类和结构体扩展方法
    extension可以对一个类进行扩展,也可以给一个类扩展协议方法

    扩展类的方法
    1.//使用Extension给类扩充一个方法

    extension ErShiXiong
    func eat(){

    print(“吃饭”)
    }
    }

    let er = ErShiXiong()

    er.eat()

    //extension除了可以给类扩展方法以后,还可以给类扩展实现协议

    .//先声明一个协议MyProtocol

    @objc protocol MyProtocol {

    optional func test () //该法方法可选实现
    func test()
    }

    extension ErShiXiong:MyProtocol {
    func test() {
    print(“Hello”)

    }
    }


    五、闭包

    闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift中的闭包与C和Objective- C的代码块(block)以及其他一些编程语言中的匿名函数比较相似。

    闭包可以捕获和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift会为您管理在捕获过程中涉及到的素有内存操作

    闭包表达式语句

    if。语法形式

    {
    (参数) - >返回值类型 in
    执行语句
    、}

    let backString = {
    (name:String)->String in
    return name

    }


    注意:闭包的函数体部分由关键字in引入,该关键字表示闭包的参数和返回值类型定义已经完成,闭包函数体即将开始


    闭包的使用

    使用闭包实现就两个int型数的最大值


    var maxValue:((int,int)->int)

    maxValue = { (a:int,b:int)->int in
    return a > b ? a:b
    }

    print(maxValue(3,5))

    其中:
    1、maxValue的类型是(int,int)-> int

    2、maxValue的值就是一个闭包:
    { (a:int,b:int)->int in

    return a > b ? a: b}

    3、其中上面的闭包还可以写成:

    {a,b in a > b ?a:b}或者maxValue = {$0>$1?$0:$1}

    闭包传值

    创建一个工程,勾选swift语言,创建两个控制器

    给第一个控制器添加导航控制器,点击按钮push到第二个控制爱,在第二个页面添加个按钮,点击返回第一个页面

    class SecondViewController:UIViewController {
    //声明参数为String,无返回值的闭包变量
    var block = {

    (struct:String)->Void in

    }

    闭包传值

    在第二个控制器的viewDidLoad()方法创建一个返回按钮

    super.viewDidLoad ()

    let button:UIButton = UIButton (fram: CGeRctMake(10,100,50,50))


    button.addTarget(self,action:Selector(“buttonAction”),forControlEvents:UIControlEvents.TouchUpinside)

    button.setTitle(“返回”,forState:UIControlState.Normal)
    button.backgroundolor = UIColor.redColor()
    self.View.addSubview(button)

    }

    返回按钮的方法实现

    fun buttonAction(){
    //闭包调用

    self。block!(“block返回值”)


    self.navigationController?.popViewControllerAnimated(true)

    }

    在一地个控制器的viewDidload()方法里创建一个push按钮
    override func viewDidLoad(){
    superviewDidLoad()
    let button:UIButton = UIButton(frame:CGRectMake(10,100,50,50))

    button.addTarget(self.action:Selector(“pushAction”),forControState.Normal)

    button.backgroundColor = UIColor()
    self.view.addSubview(button)

    }


    第一个控制器的push按钮方法实现


    func pushAtion () {

    let secondVC:SecondViewController = SecondViewController()

    secVC.View.backgroundCoor = UIColor.orangeColor()
    //闭包实现,拿到传回的值

    secondVC.block = {
    (str:String) - >Void in
    print(str)
    }

    self.navigationController?.pushViewController(SecondVC,animated:true)

    }

    //MARK: - ?和!的区别
    
    //?代表可选类型,其实值是枚举类型,里边有None和Some两种类型,其实nil值相当于OPtional.None,如果有值相当于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)
        
    }
    
    
        //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 {
                //set {
            set {
                x = newValue
            }
            //get 方法 (必须得有)
            get {
                return x/2
            }
        }
        
        var centerY:Float {
            return y/2
        }
        
        //声明方法
        //声明一个结构体变量方法 (相当于OC中的实例方法)
        
        func frameInfor(){
            print("x:(x),y:(y),(width),height:(height)")
        }
        //声明一个结构体方法(相当于OC中的类方法),使用static修饰
        static func info() {
            print("这是结构体方法")
        }
        
    }
    
    
    //1.根据结构体去定义一个结构体变量
    
    var fram = Rect (x: 10, y: 10,  100, height: 100)
    
    
    //2.访问结构体变量中的属性
    
    //注意:结构体变量中的属性类型可以使用let去修饰,只不过访问的时候不能对其进行修改
    
    fram.x = 20
    
    print(fram.x)
    
    //3.访问结构体属性
    
    Rect.description = "我就是结构体属性"
    
    print(Rect.description)
    
    //4.访问计算属性
    
    fram.centerX = 200 ; //这句话就相当于调用centerX的setter方法
    
    let value = fram.centerX //这句话就相当于在调用centerX的getter方法
    
    print(value)
    
    
    //5.调用结构体变量方法
    
    fram.frameInfor()
    
    //6.调用结构体方法
    
    Rect.info()
    
    //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?
        
        //计算属性
        var value:Int {
            set(a) {
                age = a  //在写计算 的时候,一定不能出现self,否则会早晨死循环
            }
            get {
                return age!
    }
        }
        
        //声明一个类方法
        //1.在类方法前边加上 static修饰 [虽然是一个类方法,但是该方法在子类中不能进行重写]
        static func sayHi (){
            print(introduce) //注意:在类方法中只能使用类方法,不能使用对象属性
        }
        //2.在类方法前面加上class修饰 [它是一个类方法,可以被子类重写]
        
        class func sayHi1() {
            print(introduce)
        }
        //声明一个实例(对象)方法
        func sayHi2() {
            print("hello,我是实例方法")
        }
        
    }
    
    //1.创建对象 [此时应该注意和OC区别分开,实例对象,后边根的是类](注意:要初始化对象一定要写初始化构造的方法)
    
    var person1:Person = Person(name: "MBBoy", age: 20)
    
    
    //2.访问类中的属性(对象属性)
    
    print(person1.name!)
    
    //3.访问类属性
    
    Person.introduce = "我是XXXX"
    
    //4.访问计算属性
    
    person1.value = 20
    
    print(person1.value)
    
    //5.访问类方法
    
    
    Person.sayHi()
    Person.sayHi1()
    
    
    //6.访问实例方法
    
    person1.sayHi2()
    
    //定义一个子类,继承Person,继承Person
    
    //在swift中不支持多继承
    
    class Student:Person {
        
        //重写父类的方法
        //重写父类中的类方法
        
        override class func sayHi1() {
            print("我是子类Student类,重写了父类的类方法")
        }
        
        //重写父类中的实例对象
        
        override func sayHi2() {
            print("我是子类Student类,重写父类中的实例对象")
        }
        
    //    var student = Student(name: <#T##String#>, age: <#T##Int#>))
        
    }
    
    //初始化Student对象
    
    var student = Student(name: "张三", age: 25)
    
    Student.sayHi1()
    student.sayHi2()
    
    //MARK: - 值类型和引用值类型的区别
    
    
    //值类型
    /*
    struct animal {
        var name:String?
        var age:Int?
        
        
        init(name:String,age:Int) {
            self.name = name
            self.age = age
        }
    }
    var dog = animal(name: "贝贝", age: 3)
    var dog1 = dog //此时将dog的数据拷贝给dog1
    
    dog.name = "欢欢"
    
    print("dog.name:(dog.name!)")
    
    print("dog1.name:(dog1.name!)")
    
    */
    /*
    //引用值类型
    class animal {
        var name:String?
        var age:Int?
        
        init (name:String,age:Int) {
            self.name = name
            self.age = age
            
        }
    }
    
    var dog = animal(name: "贝贝", age: 3)
    
    var dog1 = dog
    
    dog.name = "欢欢"
    
    print("dog.name:(dog.name!)","dog1.name:(dog1.name!)")
    
    
    */
    
    //MARK: - 协议(protacol)
    
    
    //当swift中声明协议的时候,协议里有可选方法需要使用@objc关键字修饰
    
    
    @objc protocol MarryDlegate {
        
        
        func cook() //做饭
        
        func wash() //洗衣服
        
        optional func hitDouDou () //打豆豆
        
    }
    
    protocol DivorceDelegate {
        func diviceMonkey() //分割财产
        
        
    }
    //如果一个类要遵循协议的时候,如果这个类有父类,要在:后先写父类,然后,再写遵循的协议
    class Man:Person,MarryDlegate,DivorceDelegate{
        @objc func cook() {
            print("还好去新东方学了几年的厨艺,终于可以大展身手")
        }
        @objc func wash() {
            print("还好买了台洗衣机")
        }
        func diviceMonkey() {
            print("分财产")
        }
    }
    
    //创建一个男人
    
    let man = Man(name: "韦小宝", age: 22)
    
    man.cook()
    man.wash()
    
    
    man.diviceMonkey()
    print("分割财产")
    
    
    //MARK: - 扩展(Extension)
    
    //1.扩展协议中的相关方法
    
    extension Man {
        @objc func hitDouDou() {
            print("老婆,I Miss U")
        }
        
        
    }
    
    man.hitDouDou()
    
    //2.扩展还可以扩展类方法(给某一个类添加方法,类似于OC中的category类目)以及对象方法
    
    
    extension Man {
        //扩展一个对象方法
        func sing (){
            print("老婆,老婆,我爱你")
        }
        //扩展一个类方法
        class func sleep() {
            print("多喝水,早睡觉")
        }
    }
    
    
    man.sing()
    Man.sleep()
    
    
    //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 //切记不能忘记in
        
        
        return num1 > num2 ? num1 : num2
    }
    
    
    //第二种方式
    
    myBlock = {
        num1,num2 in
        
        return num1 > num2 ? num1 : num2
    }
    
    //第三那种方式
    
    myBlock = {
        num1 , num2 in
        
        num1 > num2 ? num1 : num2
    }
    
    
    //第四种方式
    myBlock = {
        $0 > $1 ? $0 : $1
    }
    
    //第五种方式
    
    myBlock = {
        (num1, num2)->Int in
        
        return num1 > num2 ? num1 : num2
    }
    
    
    
    
    
    
    let max = myBlock(num1: 88, num2: 66)
    
    print(max)
    

      

  • 相关阅读:
    ListNode Java创建链表
    Remove Nth Node From End of List LeetCode Java
    Rotate List LeetCode Java
    LeetCode刷题感想
    Swap Nodes in Pairs LeetCode Java
    Reverse Nodes in k-Group LeetCode Java
    334. Increasing Triplet Subsequence
    300. Longest Increasing Subsequence
    130. Surrounded Regions
    200. Number of Islands
  • 原文地址:https://www.cnblogs.com/mingjieLove00/p/5520905.html
Copyright © 2011-2022 走看看