swift初始化常见错误

作者: coderhlt | 来源:发表于2018-08-20 18:44 被阅读0次

importUIKit

前言:swift的初始化过程真的比oc的初始化难啊难,需要反反复复看。为了更好地理解、快速上手swift,记录一些常见的错误例子。

错误一:存储属性没有被初始化

  • eg1:
class Student{

    var name:String

}

报错:Class 'Student' has no initializers

  • eg2:
class Student{

var name:String

init() {



  }

}

报错:Return from initializer without initializing all stored properties

类和结构体在创建实例时,必须为所有存储型属性设置合适的初始值。存储型属性的值不能处于一个未知的状态,因此eg1和eg2报错都是因为属性没有被初始化造成的。我们可以在构造器中为存储型属性赋初值,也可以在定义属性时为其设置默认值。

class student {

var name:String

init() {

name = ""

  }

}
class student {

var name = ""

}

错误二:在调用父类的初始化方法前,自身的存储属性未被初始化

class Student:NSObject{

var name:String

override init() {

super.init()

self.name = ""

}

}

报错:Property 'self.name' not initialized at super.init call

指定构造器必须保证它所在类引入的所有属性都必须先初始化完成,之后才能将其它构造任务向上代理给父类中 的构造器。一个对象的内存只有在其所有存储型属性确定之后才能完全初始化。为了满足这一规则,指定构造器

必须保证它所在类引入的属性在它往上代理之前先完成初始化。而例子中我们却刚好违背了这一原则,student的name属性还未初始化就调用了父类的初始化。

纠正:

Student:NSObject{

var name:String

override init() {

self.name = ""

super.init()//可以省略,系统会自动调用

}

}

错误三:在调用父类的初始化方法前,自身的存储属性未被初始化并未调用其直接父类的的指定构造器

  • eg1:
 class student: NSObject {

      init(name:String) {

      super.init()

    }

  }

不报错

class view: UIView{

    init(name:String) {

    super.init()

  }

报错:Must call a designated initializer of the superclass。

也许这是你会想到oc的它们的自定义构造:

@implementation student

- (instancetype)initWithname:(NSString *)name{

self = [super init];

if (self) {

}
return  self;

}
@end

@implementation view
- (instancetype)initWithname:(NSString *)name{

self=[super init];

if (self) {

}
return self;

}
@end

嗯,嗯oc这里的确没毛病。而swift就不一样了,swift的指定构造器必须调用其直接父类的的指定构造器。注意了是:“直接”(重要的强调三遍)父类的指定构造器。eg1中student的直接父类构造器就是super.init()没毛病,而eg2中的view的父类直接构造器不是super.init(),它是 super.init(frame: CGRECT)

纠正:

  init(name:String, frame:CGRect) {
  super.init(frame: frame)
}
  required init?(coder aDecoder: NSCoder) {

  fatalError("init(coder:) has not been implemented")

    }//自定义view必须写上这个方法,即时我们不从xib或storboard加载view,要不然编译会报错

错误四:调用父类构造器之前访问了父类的属性

class person{
var age = 12
}
class student: person {
var name = ""
init(age:Int,name:String) {
self.age = 11
}
}

报错:'self' used in property access 'age' before 'super.init' call

指定构造器必须先向上代理调用父类构造器,然后再为继承的属性设置新值。如果没这么做,指定构造器赋予的 新值将被父类中的构造器所覆盖。也就是在这个例子中,我们先访问了继承父类的age属性,系统后调用了super.init造成错误。

纠正:

  class person{
var age = 12
}

class student: person {
var name = ""
init(age:Int,name:String) {
super.init()
self.age = 11
}
}

五给扩展类添加新的指定构造器或析构器

extension UIBarButtonItem{
    init(age:String) {

    }

}

报错:Designated initializer cannot be declared in an extension

扩展能为类添加新的便利构造器,但是它们不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。因此在为分类增加扩展的方法,我们需要提供便利构造器。

纠正:

extension UIBarButtonItem{

convenience init(age:String) {

let btn = UIView()

self.init(customView: btn)

  }

}

相关文章

  • Swift编程一(快速之旅)

    案例代码下载 关于Swift Swift通过采用现代编程模式来定义大类常见的编程错误: 变量在使用前始终初始化。 ...

  • swift初始化常见错误

    importUIKit 前言:swift的初始化过程真的比oc的初始化难啊难,需要反反复复看。为了更好地理解、快速...

  • 1.Swift特性

    Swift 通过采用现代编程模式来避免大量常见编程错误: 变量始终在使用前初始化。 检查数组索引超出范围的错误。 ...

  • swift常见错误

    最近工作比较忙,有大半年都没有看过swift代码了。也有很久没写过博客了,今天将当初学习swift的时候,总结的几...

  • swift使用常见错误

    以前的老项目运行的时候容易报错类似:SWIFT_VERSION '3.0' is unsupported, sup...

  • Swift5.1学习随笔之错误处理Error

    开发中常见的错误 语法错误 逻辑错误 运行时错误(导致闪退) 自定义错误 Swift可以通过自定义Error协议来...

  • Swift 5.1 (14) - 初始化和反初始化

    Swift 5.1 (14) - 初始化和反初始化Swift 5.1 (14) - 初始化和反初始化

  • 25、【Swift】内存安全

    Swift 安全性使用前就初始化内存在变量释放后不能再访问数组会检查越界错误 Swift 还通过要求标记内存位置来...

  • swift 自定义UIView构造函数

    swift 自定义初始化构造函数有点麻烦 上代码 成员成员变量必须要赋值初始值,不然会报没有初始化成员变量的错误 ...

  • Swift中的Error处理

    错误类型 1、开发过程常见的错误 自定义错误 1、Swift中可以通过Error协议自定义运行时的错误信息 2、函...

网友评论

    本文标题:swift初始化常见错误

    本文链接:https://www.haomeiwen.com/subject/knaliftx.html