标签:
Senior进阶
Swift(一)
一、Swift简介
2010年的夏天,苹果公司的开发人员 Chris Lattne 接到了一个特别的任务,为OSX何iOS平台开发下一代的编程语言,也就是Swift。
苹果公司于2014年WWDC(苹果开发者大会)发布的新开发语言Swift,可与Objective-C共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序。
2015年的WWDC开发者大会上,苹果公司推出了Swift2.0版本,并且Swift完全开源。
自从Swift发布以来,在http://www.tiobe.com中的排行一直处于上升的状态。
在Swift中使用"let"修饰一个常量,使用var修饰一个变量
let修饰常量的值是不可以更改的;
var修饰的变量的值是可以更改的;
在声明常量和变量的时候可以使用表情符号、中文等命名常量名和变量名。
Swift定义变量或者常量的时候,需要标识出变量或者常量的类型,如果不标识,会根据初始值自动推断,
如:
//会自动推断变量a为Int类型
var a = 10
//会自动推断常量b为String类型
let b = "Hello"
Int、 Float、Double、String、Charater(字符使用双引号,但是里面只能放单个字符);
例如:
let a:int = 10
let b:Srting = "Hello"
let c:Character = "A"
let flag:Bool = false
注意:值永远不会被隐式转换为其他类型:如果你需要把一个值转换成其他类型,请限式转换
let name ="Lanou‘s age is‘‘
let age = 3
let words = name +String(age)
字符串
1、String是有序的字符集合,例如"Hello 蓝鸥"
2、Swift中的字符串通过String类型表示,当然也可以看成Character字符类型的集合
(1).//定义字符串变量
var var_str = "Hello 蓝鸥"
(2).//创建空String变量
//这两个字符串都为空,并且两者等价
var empty_str1 = ""
var empty_str2 = String()
(3).//通过字符串对象的isEmpty方法判断是否为空
if empty_str1.isEmpty {
print ("‘empty_str1 is empty
")
}
(4).//字符串连接
//创建字符串变量
var var_str = "http://"
//字符串拼接后,var_str = "http://www。lanou3g.cm"
var_str += "www.lanou3g.com"
注意:let con_str = "hello"常量不能被修改!!
(5).//创建字符串常量
let con_str = "Hello"
//获取字符串的长度
let length = con_str.characters.count
(6).//字符串插值
let mul = 3.0
let content = "\(mul)x2.5 = \(mul*2.5)"
(7.)//字符串比较
let name1 = "xiaohao"
let name2 = "lanou3g"
if name1 == name2
print("\(name1)equals\(name2)")
else {
print("not equal")
}
Swift2
一、可选类型(?)
在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 width: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:\(width),height:\(height)")
}
//声明一个结构体方法(相当于OC中的类方法),使用static修饰
static func info() {
print("这是结构体方法")
}
}
//1.根据结构体去定义一个结构体变量
var fram = Rect (x: 10, y: 10, width: 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)

标签:
原文地址:http://www.cnblogs.com/mingjieLove00/p/5520905.html