在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum Celebrity{ case DongXie,XiDu,Nandi,BeiGai } // 从左到右对应0,1,2,3 enum CompassPoint { case North case South case East case West //enum中可以定义方法 func show(){ print(self) } } //定义enum 变量 var p = CompassPoint.North var p2 = CompassPoint.South p.show() p2.show()
var point:CompassPoint = .West
switch point{ case .North: print("北") case .South: print("南") case .East: print("东") case .West: print("西") } enum Week:Int { case Sun, Mon, Tur, Wen, Thu, Fri, Sat } //原始的(裸值)需要进行类型标注, // notice:这里通过调用枚举类型 Week 调用 枚举成员Sun 裸值(及C中所述的枚举整型值),需要在赋值的变量后面加上的的类型标示符号 var weekDay:Int = Week.Sun.rawValue //也可以直接通过Week的 rawValue方法调用得道当前的 枚举成员 var week:Week? = Week(rawValue:7) //这里如果rawValue 超出了枚举值的返回,则返回为空,所以week需要使用可选值来接收 //还可以利用元组特性设置关联的枚举成员 enum BarCode { case UIPCA(Int,Int,Int) //条形码 case QRCode(String) //二维码 } //定义个枚举变量 var barcode = BarCode.UPCA(690,3322323,2) barcode = Bar.QRCode("http://fdsafdsfa.com") switch barcode { case BarCode.UPCA(let(num,id,check)): print("这是一个条形码 \(num)-\(id)-\(check)") case BarCode.QRCode(let string): print("这是一个二维码 对应的字符串是:\(string)") } }
/**使用新的写法,在绑定变量的同时,指定条件判断,类似于SQL*/ switch aPoint { //在绑定一个变量的同时,可以绑定x == y case let(x,y) where x == y: print("x 与 y相等斜线上 x = y") case let(x,y) where x == -y: print("x 与 -y斜线上 x = -y") default: print("other") }
2. 结构体和类: 相同点: 结构题和类,都在定义一种类型 都可以在内部定义属性和方法 都可以定义下标运算符 都可以定义初始化方法(Int 初试化器, 构造器 构造方法) 都可以使用扩展现有的功能(OC中有分类,Swift中没有分类,叫扩展) 都可以遵循制定的协议 不同点: 类可以继承,结构体不能 类有多态,结构体没有 类的内存支持自动引用技术,结构体不支持引用技术,结构体变量都是在栈中分配内存空间,不需要手动管理 类是引用类型 结构体是值类型 //属性的初始化就提供了一个无参 和统一的初始化器 struct Resolution { var width = 0.0 var height:Float = 0.0 } //类中申明属性必须进行初始化,除非它是可选值 class VideoMode { var resolution = Resolution() var interlocaed = false var frameRate = 0.0 var name:String? } //结构体是值类 类是引用类型 var res = Resolution() var res2 = res res.width = 1024 res2.width
var vmode = VideoMode() var vmode2 = vmode vmode.name = "zhanshang" vmode2.name /** ===比较地址是否相等*/ if vmode === vmode2 { print("两个引用是同一个值") } if vmode2 !== vmode { print("两个引用不是同一个地址") } /** 结构体的统一初始化器,这与C中的结构题嵌套非常相识,紧紧是指把变量的定义方式改变了一下,另外支持 点语法访问层级嵌套属性*/ struct Point { var x :Float var y :Float } struct Size { var w :Float var h :Float } struct Rect { var origin: Point var size: Size } var rect = Rect(origin: Point(x: 100, y:20), size: Size(w : 2 ,h: 3)) rect.size.w rect.origin.x
3. 属性,在Swift中属性有两个分类方式 第一种方式: /** 1. Swift中属性有两个分类方式 第一种方式: -> 存储属性(Stored Properties):用变量或者常量来保存属性值 -> 计算属性(calculate Properties): 通过计算得来的。 举例: 出生日期: 存储树形 , 年龄:需要通过两个时间进行计算 -> 第二中分类方式: 实例属性 和 类型属性 */ // 存储属性 struct MyRange { var location:Int let length:Int } var myRnage = MyRange(location: 0, length:100) struct Point { var x = 0.0, y = 0.0 }
struct Size { var w = 0.0, h = 0.0 } struct Rect { //存储属性,使用变量或者常量来保存存储属性 var orign = Point() //创建 point对象 var size = Size() var center: Point { get{ let centerX = orign.x + size.w * 0.5 let centerY = orign.y + size.h * 0.5 return Point(x: centerX, y: centerY) //返回一个point类型 } //这里如果没有参数 则使用默认的 newValue set{ let newOrignX = newValue.x - size.w * 0.5 let newOrignY = newValue.y - size.h * 0.5 orign = Point(x: newOrignX, y: newOrignY) //实现origin的赋值 } /* set(newCenter){ let newOriginX = newCenter.x - size.w * 0.5 let newOriginY = newCenter.y - size.h * 0.5 origin = Point(x: newOriginX, y: newOriginY) } */ //假设做一个只读的计算属性 } //如果只读计算属性,只有一行代码可以省略return var center2:Point { get { return Point(x: 500 + 100,y: 100) } } } var rect = Rect(orign:Point(x: 0, y: 0), size: Size(w:300,h: 200)) rect.center.x rect.center.y rect.center = Point(x: 200, y: 200) rect.orign.x rect.orign.y
/** 延迟属性 类似 OC的懒加载,或者延迟加载*/ class DataImporter { init(){ print("DataImporter create") } var fileName = "data.txt" //这个需要用到的时候才去加载 } class DataManager { lazy var dataImporter = DataImporter() } //创建DataManager这个对象 var dataManager = DataManager()
/**在需要执行懒加载的属性前面加上layz*/ dataManager.dataImporter
4. 属性监视器:是一段代码,这段代码会在属性发生变化的时候自动调用 ->计算属性,延迟属性,不能设置监视器,只有存存储属性才能设置监视器 ->属性监视器,在属性初始化的时候不调用 ->属性监视器有两种,willSet,didSet class StepCounter { var labelText = " text content" /**storeage property*/ var a :Int = 10 //只读计算属性 var b:Int { return 10 } // 给属性 加属性监视器 var totalSteps:Int = 10 { willSet (newValue){ print("属性将要变化时调用 要改变成\(newValue) 现在是\(totalSteps)") } didSet{ print("属性值已经发生改变了嗲用原来的值时\(oldValue)现在是\(totalSteps)") labelText = "改变的值时\(totalSteps)" } } } var propertyName:Int = 10{ willSet(newValue){ //inserCode here } didSet{ //insertCode here } } var stepCounter = StepCounter() stepCounter.totalSteps = 50 stepCounter.labelText
stepCounter.totalSteps = 20 stepCounter.labelText
5. 类型属性: 在结构体或者枚举中,使用static修饰的属性以及在类中使用class关键字修饰的属性叫做类型属性,属于整个类和对象无关。 在struct 中定义的类型属性,可以是存储属性,也可以是计算属性 在class 中定义的类型属性,只能是计算属性(如果需要使用存储树形座位设计类型属性,可以加上static关键字)
struct SomeStrut { //存储属性 var a = 10 //计算属性 var b:Int { return 10 } //类型属性 static var x = 10 static var y:Int { return 10 } }
var someStruct1 = SomeStrut() someStruct1.a //10
var someStruct2 = SomeStrut() someStruct2.a //10
SomeStrut.x //10 SomeStrut.y //10
class SomeClass { var a = 10 var b :Int { return 10 } /** 类型属性,太奇葩了*/ static var y :Int { return 100 } class var x:Int { return 100 } static var storeagePorperty:Int = 10 //编译通过。优先使用static // Swift编译无法通过❌class var storagePorperty1:Int = 100 } SomeClass.y SomeClass.storeagePorperty = 123 SomeClass.x 6.实例方法,类方法,几乎同OC一样
//实例方法 与类方法,类中的实例方法几乎和OC一样 /** 类类型的实例方法*/ class Counter{ var count = 0 func increment(){ count++ } func incrementBy(amount: Int){ count += amount } func incrementBy(amount: Int ,numberOffTimes: Int) { count += amount * numberOffTimes } }
/** create a instance */ var counter = Counter()
/** invoke instance method*/ counter.increment()
/** 值类型的实例方法 */ struct Point { var x = 10, y = 10 //实例 值类型属性,由对象调用,或者对象 self指针调用 var z = 250 static var sx = 10 //类类型属性,由类调用,或者类 self指针调用 func show() { print("点点\(x)") Point.sx = 1111 } //值类型的实例方法,默认不可以修改实例属性,如果非要修改则加上mutating mutating func setX(px: Int,AndY y:Int) { // x = px self.x = px //防止参数和属性重名 self.y = y Point.sx = 111 } }
enum StatusSwitch{ case Study,Dining,Review,Sleep func show(){ switch self{ case .Study: print("正在学习") case .Dining: print("正在吃饭") case .Review: print("正在复习") case .Sleep: print("正在睡觉") } } /** 切换状态, 这里如果想修改self需要在前面加上 mutating*/ mutating func nextStatus(){ switch self { case .Study: print("下一步吃饭") self = .Dining case .Dining: print("下一步 去复习") self = .Review case .Review: print("下一步 去睡觉") self = .Sleep case .Sleep: print("下一步 去学习") self = .Study } } } var ss = StatusSwitch.Study ss.show() ss.nextStatus() ss.nextStatus() ss.nextStatus() ss.nextStatus() ss.nextStatus() ss.nextStatus() ss.nextStatus() ss.nextStatus()
7. 类型方法:
//类型方法 和 OC中的类方法,含义相同 class SomeClass { var prop:Int = 0 //实例属性必须要有了对象之后能方位
class var a:Int { //类属性 ,class也可以使用static return 10 } func instanceMethod() { print("this is a instance method") self.prop SomeClass.a //self.a a为类属性,所以无法调用 } class func typeMethod(){ // class func 代表定义个类方法 print("这是一个类型方法") //同OC,类方法中不能访问实例属性,但是可以访问类型属性 // self.prop self.a //self带表调用这个方法的对象,self相当于调用类方法的对象,类对象 SomeClass.a } }
var p = SomeClass() p.prop SomeClass.a
//类方法的调用 SomeClass.typeMethod()
//先创建一个类的对象-》 var instanceObject = SomeClass() //类名+()可以创建一个类的对象 instanceObject.prop instanceObject.prop = 10 instanceObject.prop
struct SomeStruct { var prop:Int = 0 /**声明一个static的存储属性*/ static var a: Int = 0 func show(){} func instanceMethod(){ //此处实例属性可以读但是不能修改 prop = 1000,如果需修改采用 self.show() print(prop) } /**结构体中, 类方法使用static,在类中可以使用static和class定义类方法和变量方法, C++里面叫做静态方法,但是在结构体中只能是static */ static func typeMethod(){ print("这是一个类型方法") //self.show() 实例方法,❌,此处无法使用 } }
/**枚举中 类型方法*/ enum StatusSwitch { case Study,Dinig,Review,Sleep static func typeMethod() { print("这是一个类型方法") } static func create()->StatusSwitch { return self.Study //StatusSwitch 类对调用 create 类方法,self 指向StatusSwitch,所以返回为StatusSwitch类型 } func show() { print("这是一个实例方法") } }
StatusSwitch.create().show() // StatusSwitch.Study.show() //与上面等价 //枚举成员可以调用枚举类的方法,这样理解会好记一点,搞不明白的就暂时当成一种格式来记,等代码积累量上去了再回过头来研究。 8. 下标脚本,主要用于检查数组边界是否越界;使用断言的方式 class MyArray { //private 私有的,越界返回真,不越界返回假 pravate var array = [0,1,2,3,4,5,6,7,8,9] func indexIsValid(index:Int) -Bool { if index < 0 || index >array.count - 1 { return ture } else { return false } /**增加数据*/ func addObjectAtIndex(index:Int ,object:Int) { assert(indexIsValid(index)) array.insert(object,atIndex:Index) } func show(){ print(array) } } //让MyArray支持下标,写法一 定义一个 通过subscript构建一个整型的下标函数,创建set 和 get方法,其中set方法中newValue和数组赋值时,外界传入的形参 subscript(index:Int)->Int { get { return array[index] } set { array[index] = newValue } } 方法二:通过改写set方法 subscript(index:Double)->Int { get{ return array[Int(index + 0.5)]} set{ array[Int(index + 0.5)] = newValue } //此处的newValue为set方法调用时外部带的参数 类似于 (int)setnewValue:(int)newValue } var myArray = MyArray() myArray.show() myArray.addObjectAtIndex(1, object: 100) myArray.show() myArray.array + [30,300] myArray.array.removeAtIndex(5) myArray.show() myArray.array[0] 9. 继承: 父类 子类 (基类,派生类) Swift中的特点: 一个类可以没有父类,不像OC所有的类都继承于NSObject,Swift中是单即成类,一个类只能由一个父类,但是可以有多个子类。 class Vehicle { //存储属性 storage properties var currentSpeed = 0.0 //计算属性 calculate properties var description:String { return "当前速度是每小时\(currentSpeed)公里" } func makeNoise() { print("父类发生的方法") } func show(){ print("父类显示的方法") } }
/** inheritance*/ class Bicycle: Vehicle { /** extension propertie*/ var hasBasket = false
/** extension method*/ func test(){ print("subClass extension method") } /** override parent method*/ override func makeNoise() { print("subClass dong dong ...") } } var bike = Bicycle() bike.show() bike.makeNoise() bike.hasBasket bike.currentSpeed
/**父类型指向子类型,前面obj为交通对象,makeNoise重写后被覆盖,先调用子类的方法 */ var obj:Vehicle = Bicycle() obj.makeNoise() } /** 覆盖父类的方法只需要在方法前面使用override关键字, override func 。。。。 重写父类属性只需要在子类定义与父类相同的属性,并在后面加上{ didSet{ //inertCode 需要重写的内容 } } 在父类中 变量和方法前面只要加上 final关键字则表示该方法不能被重写 */
class Car : Vehicle{ var gear = 1 // 重写覆盖父类的方法 override func makeNoise(){ print("汽车滴滴") } // 重写计算属性 override var description : String { return super.description + "在\(gear)档上" } // 重写父类的存储属性 override var currentSpeed : Double{ didSet{ gear = Int(currentSpeed/10.0) + 1 } } } var car = Car() car.gear car.currentSpeed = 40 car.description car.gear
/*final */ class Base { // 限制这个类不能被继承 final var a = 10 // final 不能被重写 final func show(){ } //final 的方法不能被重写 }
class Child: Base {
}
// 开发中还有一种常见的形式 组合 class Radio{ var price : Double = 0.0 func radio(){ print("收听广播") } }
class MyCar{ var radio = Radio() }
var mc = MyCar() mc.radio.radio() mc.radio.price = 10000000 |
请发表评论