程序员首页投稿(暂停使用,暂停投稿)iOS Developer

Swift超基础语法(类与函数篇)

2016-08-02  本文已影响93人  S_Lyu

"现在外面整刮着14级台风...我居然还能镇定的用手机4G网写完这篇文章"
"无论内容如何...别说话,赞我"
---2016.8.2 广州

类与函数

在Swift中与类息息相关的两个函数莫过于构造函数析构函数了,那么似曾相识的构造函数在Swift是怎么样表现的,析构函数又是怎么一回事呢?

class Person : NSObject{
        var name : String
        var age : Int
        override init() {
            name = ""
            age = 0
        }
}
class personItem : NSObject {
      var name : String
      var height : Double
      var age : Int
      init(name : String , height : Double , age : Int) {
          self.name = name
          self.height = height
          self.age = age
      }
}
例:基本的字典转模型方法
class personItem : NSObject {
      var name : String
      var height : Double
      var age : Int
      init(dic : [String : NSObject]){
          self.name = dic["name"] as! String
          self.height = dic["height"] as! Double
          self.age = dic["age"] as! Int
      }
}
//外界调用
        let dic = ["name" : "lyu" , "height" : 1.80 , "age" : 18]
        let item = personItem(dic: dic)
例:使用KVC进行字典转模型
class personItem : NSObject {
      var name : String?  //注意:使用KVC模式赋值必须先对所有成员变量进行初始化赋值,这是因为KVC并不一定能给所有成员变量都赋值,所以需要我们先手动赋值,并且配合super.init()方法来初始化成员变量
      var height : Double = 0.0  //注意:基本类型不能是可选类型,否则KVC转换失败(结果为nil)
      var age : Int = 0
      init(dic : [String : NSObject]){
          super.init()  //注意,使用KVC为成员变量赋值,必须先进行初始化
          setValuesForKeysWithDictionary(dic)
      }
      //当模型的成员变量中没有外界传来的字典中的某一个key的时候,程序会崩溃,为了解决这个问题,我们重写了如下方法,并且放空其实现
      override func setValue(value: AnyObject?, forUndefinedKey key: String) {} 
}
//外界调用
        let dic = ["name" : "lyu" , "height" : 1.80 , "age" : 18 , "sex" : 1]  //注意,模型中并没有sex这个属性,然而程序并不会崩溃,这就是我们改写了上面这个方法的好处
        let item = personItem(dic: dic)
Tips:
析构函数不可以手动调用,他会在实例被释放的时候自动调用,这点与OC中的dealloc比较相似
格式:
deinit{
        //执行过程
}
class Person {
      var name : String?
      deinit
      {
          print("person -> deinit")
      }
}
//外部调用
        var p :Person? = Person()
        p = nil  //更改指针p的指向,原有的person实例会被释放,测试打印结果:person -> deinit
Tips:
nil的内存地址是0x0
//创建两个类:
class Person {
    var dog : Dog?
    deinit
    {
        print("person -> deinit")
    }
}
class Dog {
    var owner : Person?
    deinit
    {
        print("dog -> deinit")
    }
}
//外部调用:
        //实例化两个对象
        var person : Person? = Person()
        var dog : Dog? = Dog()
        //让两个实例相互拥有
        person?.dog = dog
        dog?.owner = person
        //试图去销毁两个实例
        person = nil //然而此时并没有调用deinit函数,也就意味着两个实例均没有被销毁,于是出现循环引用问题
        dog = nil
class Person {
    weak var dog : Dog?  //Person类弱引用Dog属性,此时外界使用相同的代码调用就不会出现循环引用的问题了
    deinit
    {
        print("person -> deinit")
    }
}
class Person {
    unowned var dog : Dog = Dog()  //注意,unowned不能修饰可选类型,unowned修饰的指针不可以指向nil,这恰恰与可选类型(可空类型)矛盾
    deinit
    {
        print("person -> deinit")
    }
}
Tips:unowned与weak
相同点:都不会给修饰的对象的引用计数+1
不同点:weak修饰的对象被销毁,那么这个指针会自动指向nil
unowned修饰的对象被销毁,这个指针依然会指向原来的内存地址,变成野指针,这很容易引起访问僵尸对象的错误
上一篇 下一篇

猜你喜欢

热点阅读