转载

每日一博 | 让你 2 小时学会 Swift

过年不能闲着,一边学习Swift,一边写笔记,相信在有一定其他语言基础的情况下用1.5小时看完该文章即可掌握。然后再花30分钟打开XCode写个Demo.

生命中拿出2小时来认识一门语言,很值吧!

笔记共分为两部分,一Swift基础知识,二使用Xcode开发一个软件

[TOC]

swift基础知识

变量和常量

//定义变量 var myVariable = 123  //定义常量 let myConstantVariable = 123  // 隐式指定整数类型 var anInteger = 2  // 明确指定整数类型 let anExplicitInteger :Int = 2 

元组

let aTuple = (1, "Yes") let anotherTuple = (aNumber: 1, aString: "Yes") let theOtherNumber = anotherTuple.aNumber  // = 1 

其他用法

let http404Error = (404, "Not Found") let (statusCode, statusMessage) = http404Error print("The status code is /(statusCode)") 

更多用户函数返回值,返回两个以上的值,跟golang很像

数组

var arrayOfIntegers : [Int] = [1,2,3] // 隐式指定 var implicitArrayOfIntegers = [1,2,3]  // 也可以创建空数组,但必须提供其类型 let anotherArray = [Int]()  //使用 append 函数向数组的末尾追加对象 myArray.append(4)  //数组中的任意位置插入对象 myArray.insert(5, atIndex: 0)   

字典

字典是一种将键映射到值的类型,类似Java的Map,PHP的数组

 var crew = [           "Caption": "Jean-Luc Picard",           "First officer": "William Riker",           "Second Officer": "Data" ];   crew["Captain"] // = "Jean-Luc Picard" 

控制流

if

 if 1+1 == 2 {          println("The math checks out") } 

for-in

let loopingArray = [1,2,3,4,5] var loopSum = 0 for number in loopingArray {      loopSum += number } loopSum // = 15  
var firstCounter = 0      for index in 1 ..< 10 {          firstCounter++      } // 循环9次  var secondCounter = 0 for index in 1 ... 10 { // 注意是三个句点,不是两个          secondCounter++      } // 循环10次  var sum = 0 for var i = 0; i < 3; i++ {     sum += 1  } sum // = 3 

while

var countDown = 5 while countDown > 0 {      countDown-- } countDown // = 0 
var countUP = 0 do {          countUp++ } while countUp < 5 countUp // = 5 

if-let

可以用 if-let 语句检查一个可选变量是否包 含值。如果包含,则将这个值指定给一个常量变量,然后运行某段代码。这样可以减少很 多行代码,同时又能够保证安全性

var conditionalString : String? = "a string"      if let theString = conditionalString? {          println("The string is '/(theString)'")      } else {          println("The string is nil") } // 输出 "The string is 'a string'" 

函数

单返回值简单函数

两个参数一个返回值,都为Int

func thirdFunction(firstValue: Int, secondValue: Int) -> Int {          return firstValue + secondValue      } thirdFunction(1, 2) 

使用元组多返回值

func fourthFunction(firstValue: Int, secondValue: Int)          -> (doubled: Int, quadrupled: Int) {          return (firstValue * 2, secondValue * 4)      } fourthFunction(2, 4)  // 用数字访问: fourthFunction(2, 4).1 // = 16  // 其他相同,只是使用了名字: fourthFunction(2, 4).quadrupled // = 16  

外部名称调用

在定义函数时,可以为参数指定名字。当无法马上明白每个参数的用途时,这一功能会非 常有用。可以像下面这样来定义参数名字:

func addNumbers(firstNumber num1 : Int, toSecondNumber num2: Int) -> Int {          return num1 + num2 } addNumbers(firstNumber: 2, toSecondNumber: 3)  // = 5  

在为参数创建名字时,就是为参数创建一个内部名字和一个外部名字,一个参数的内部名字应当与外部名字相同。将同一个名字输 入两次也没有什么问题,但的确有一种简便的方式来定义一个外部名字与内部名字相同的 参数——就是在参数名之前放一个 # 符号

func multiplyNumbers(#firstNumber: Int, #multiplier: Int) -> Int {          return firstNumber * multiplier } multiplyNumbers(firstNumber: 2, multiplier: 3)  // = 6 

将函数用作变量

var numbersFunc: (Int, Int) -> Int; // numbersFunc现在可以存储任何接受两个Int并返回一个Int的函数  numbersFunc = addNumbers numbersFunc(2, 3) // = 5 

闭包closure

sort需要传递一个闭包作为参数

var numbers = [2,4,34,6,33,1,67,20] var numbersSorted = numbers.sort( { (first, second ) -> Bool in          return first < second }) 

闭包只包含一行代码,可以省略 return 关键字

var numbersSorted = numbers.sort( { $1 > $0}) print(numbersSorted) 

如果一个闭包是函数调用中的最后一个参数,可以将它放在括号外面。这纯粹是为 了提高可读性,不会改变闭包的工作方式

var numbersSorted = numbers.sort(){ $1 > $0} print(numbersSorted) 

闭包放在变量里面

var comparator = {(a: Int, b: Int) in a < b} comparator(1, 2)  // = true  

对象

定义

class Vehicle {     var color: String?     var maxSpeed = 80     func description() -> String {         return "A /(self.color) vehicle"     }     func travel() {         print("Traveling at /(maxSpeed) kph")     } } 

使用

var redVehicle = Vehicle() redVehicle.color = "Red" redVehicle.maxSpeed = 90 redVehicle.travel() // 输出"Traveling at 90 kph" redVehicle.description() // = "A Red vehicle" 

继承

要重写一个函数,要在子类中重新声明它,并添加 override 关键字

class Car: Vehicle { // 继承类可以重写函数              override func description() -> String {                  var description = super.description()                  return description + ", which is a car" } } 

在一个被重写的函数中,可以通过 super 回调该函数在父类中的版本

override func description() -> String {          var description = super.description()          return description + ", which is a car" } 

初始化与反初始化

 class InitAndDeinitExample {     // 指定的初始化器(也就是主初始化器)     init() {         print("I've been created!")     }     // 便捷初始化器,是调用上述指定初始化器所必需的     convenience init (text: String) {         self.init() // 这是必需的         print("I was called with the convenience initializer!")     }     // 反初始化器     deinit {         print("I'm going away!")     } }  var example : InitAndDeinitExample? // 使用指定的初始化器 example = InitAndDeinitExample() // 输出"I've been created!" example = nil // 输出"I'm going away" // 使用便捷初始化器 example = InitAndDeinitExample(text: "Hello") // 输出"I've been created!" // 然后输出"I was called with the convenience initializer" 

创建一个可以返回 nil 的初始化器(也称为可以失败的初始化器),就在 init 关键字的后面放上一个问号,并在初始化器确定它不能成功地构造该对象时,使用 return nil:

convenience init? (value: Int) {     self.init()     if value > 5 {         // 不能初始化这个对象;返回nil,表示初始化失败 return nil     } } 

在使用一个可以失败的初始化器时,任何可以在其中存储该结果的变量都是可选的:

let failableExample = InitAndDeinitExample(value: 6) // = nil 

协议

使用协议的好处是,可以利用 Swift 的类型体系来引用任何遵守某一给定协议的对象,个人现在理解为是Interface概念。

protocol Blinking{     var isBlinking:Bool{get}     var blinkSpeed: Double { get set }     func startBlinking(blinkSpeed: Double) -> Void      }  class Light:Blinking{     var isBlinking = false     var blinkSpeed = 1.2     func startBlinking(blinkSpeed: Double) {             print("now my speed is /(self.blinkSpeed)")     }      } 

扩展

 extension Int {          var doubled : Int {              return self * 2          }          func multiplyWith(anotherNumber: Int) -> Int {              return self * anotherNumber } }  2.doubled  // = 4 4.multiplyWith(32) // = 128 

还可以利用扩展使一个类型遵守一个协议

extension Int : Blinking {     var isBlinking : Bool {         return false;     }     var blinkSpeed : Double {         get {             return 0.0; }         set {             // 不做任何事情         } }     func startBlinking(blinkSpeed : Double) {         print("I am the integer /(self). I do not blink.")     } } 2.isBlinking // = false 2.startBlinking(2.0) // 输出"I am the integer 2. I do not blink." 

访问控制

在将一个方法或属性声明为 public 时,App 中的所有人都能看到它:

// 可供所有人访问 public var publicProperty = 123  //如果将一个方法或属性声明为 private,那只能在声明它的源文件内部看到它: // 只能在这个源文件中访问 private var privateProperty = 123  // 仅能供本模块访问 // 这里的'internal'是默认的,可以省略  internal var internalProperty = 123 

运算符重载

类似C++的运算符重载

class Vector2D {     var x : Float = 0.0     var y : Float = 0.0     init (x : Float, y: Float) {         self.x = x         self.y = y     }     } func +(left : Vector2D, right: Vector2D) -> Vector2D {     let result = Vector2D(x: left.x + right.x, y: left.y + right.y)     return result }  let first = Vector2D(x: 2, y: 2) let second = Vector2D(x: 4, y: 1) let result = first + second 

泛型

Swift与Java泛型相同

class Tree <T> {     // 'T'现在可以用作一种类型 var value : T     var value:T     var children : [Tree <T>] = []     init(value : T) {         self.value = value     }     func addChild(value : T) -> Tree <T> {         var newChild = Tree<T>(value: value)         children.append(newChild)         reutrn newChild     } }   // 整数树 let integerTree = Tree<Int>(value: 5) // 可以增加包含Int的子树  integerTree.addChild(10) //用Swift设计程序 | 45 integerTree.addChild(5) // 字符串树 let stringTree = Tree<String>(value: "Hello") stringTree.addChild("Yes") stringTree.addChild("Internets") 

字符串

比较字符串

  let string1 : String = "Hello"      let string2 : String = "Hel" + "lo"      if string1 == string2 {          println("The strings are equal")   } 

查找字符串

 if string1.hasPrefix("H") {          println("String begins with an H")      }      if string1.hasSuffix("llo") {          println("String ends in 'llo'")      } 

数据

let stringToConvert = "Hello, Swift" let data = stringToConvert.dataUsingEncoding(NSUTF8StringEncoding)  

Swift with cocoa用Xcode开发软件

打开Xcode 7.2

STEP1

打开Xcode新建Project选择OSX Application

每日一博 | 让你 2 小时学会 Swift

STEP2

每日一博 | 让你 2 小时学会 Swift

STEP3

打开Main.storyboard,在ViewController中拖入Label

每日一博 | 让你 2 小时学会 Swift

STEP4

修改ViewController.swift代码

import Cocoa  class ViewController: NSViewController {      @IBOutlet weak var timestamp:NSTextField!     @IBOutlet weak var dateLabel:NSTextField!     @IBAction func calc(sender:NSButton){                  //将输入的字符串转为NSString         let string = NSString(string: self.timestamp.stringValue)                  //转为double类型         let ts:NSTimeInterval = string.doubleValue                  //转换日期         let date = NSDate(timeIntervalSince1970: ts)                  //日期格式化         let dfmatter = NSDateFormatter()         dfmatter.dateFormat="yyyy年MM月dd日"                  //显示到Label         dateLabel.stringValue = dfmatter.stringFromDate(date)     }     override func viewDidLoad() {         super.viewDidLoad()          // Do any additional setup after loading the view.     }      override var representedObject: AnyObject? {         didSet {         // Update the view, if already loaded.         }     }   }  

上述的NSTextField后面的叹号,它被称为隐式拆封的可选类型,是一种特殊类型,指出变量可能有值,也可能为nil。Swift运行 环境不喜欢访问值为nil的变量,因此Swift程序员必须知晓变量的值,尤其在其可能为nil时。将变量声明为隐式拆封的可选类型相当于告诉Swift编译器,你承诺在该变量的值为nil时绝 不会访问它。这是你与编译器签订的一个合约,你必须遵守。如果你不遵守,在变量为nil时访 问它,将引发运行阶段错误,导致应用程序停止运行

另外也可以开启两个视图直接拖入例如:

每日一博 | 让你 2 小时学会 Swift

STEP5

链接UI与代码部分,将TextField右键,选择new referencing Outlets点加号指向ViewController,在弹出的选项里面选择timestamp,同样方式选择到label上。

每日一博 | 让你 2 小时学会 Swift

绑定按钮的click事件

每日一博 | 让你 2 小时学会 Swift

STEP6

点击上方的三角箭头运行程序

每日一博 | 让你 2 小时学会 Swift

原文  http://my.oschina.net/mengshuai/blog/614396?fromerr=9Zgmw1NU
正文到此结束
Loading...