swift 语法备忘
2017-01-21 本文已影响7人
暴风鱼
swift项目中的变量作用域于JavaScript相似。
在一个文件的最外层定于的变量为全局变量,这个变量可以在别的文件中直接使用。
例:
在 file1 中定义: var x = 123
在 file2 中可以直接使用: print(x)
从这里也可以更容易理解 为什么swift定义类的文件名不要求与类同名。(因为
一个文件中可以定义多个类和其它全局范围的变量)
Foundation framework 中的类以NS开头,这个NS来自于NeXTSTEP(写Cocoa的公司)
/***********************************************
**************** 自动布局 ********************
***********************************************/
Content Hugging Priority // 抗拉能力
Content Compression Resistance Priority // 抗压能力
/***********************************************
***************** 调试器 ********************
***********************************************/
(lldb) po <变量> //打印变量 Print Object
(lldb) print <变量> //打印变量
/***********************************************
***************** 语法 ********************
***********************************************/
func go(aFunc:(Double,Double)->Double){
// something...
aFunc(1,2)
}
//通过传递一个匿名函数 调用
go({(op1:Double, op2:Double) -> Double in
return op1 + op2
})
//由于可以推断出op1 op2的类型 和返回值所以可以省略为
go({(op1, op2) in return op1 + op2 })
// 用$0 $0引用传递的参数后可进一步省略为
go({ $0 + $1 })
//还可以把这个匿名函数拿外边来
go(){ $0 + $1 }
//如果这个匿名函数是这个唯一的参数 ()也可以省略掉
go{ $0 + $1 }
// switch 语句 注意下面条件的写法
let a = "abcd"
switch a{
case "a":
print(1)
case "b","c":
print(3)
case let x where x.hasPrefix("abc"):
print("x:\(x)")
default:
print(0)
}
// if 语句 注意下面条件的写法
var a:String? = "xa"
var b:String? = "b"
// a非nil 且 a以x开头 且 y非nil
if let x = a where x.hasPrefix("x"),let y = b {
print("ok|| x->\(x) || y->\(y)")
}
// 枚举
// 枚举可以没有类型
enum e0 {
case c1
case c2
case c3
}
// 有类型时会有rawValue
enum e1:Int {
case c1
case c2
case c3
}
print(e1.c1.rawValue)
//!!!只有类的传递是传引用 类只能继承一个父类
// final类 不能被继承
// final方法 不能被override
// static 声明类方法
// Array 数组
//声明数组 迭代数组
var a = Array<String>()
var a2 = [String]()
let animals = ["Cow","Giraffe","Bird"]
//animals.append("haha") animals是不可变数组
let animal = animals[2]
for animal in animals{
print("\(animal)")
}
//Dictionary 字典
//创建字典
var d = Dictionary<String,String>()
var d2 = [String:Int]()
d2 = ["string1":1,"string2":2]
let i = d2["string2"]
let i2 = d2["xx"] //nil
//迭代字典
for(key,value) in d2{
print("\(key) = \(value)")
}
// Rang 范围
// Rang的结构类似这样
struct Rang<T> {
var startIndex:T
var endIndex:T
}
//迭代 rang 中的值
for i in [2...5]{
print("\(i)")
}
//func 函数参数
//函数参数 一个外部名 一个内部名
func foo(externalName internalName: Int)-> Int{
let local = internalName
return local
}
let result = foo(externalName: 2) //这样指定参数名 调用
//函数参数 忽略外部名 一个内部名
func foo2(internalName: Int)-> Int{
let local = internalName
return local
}
let result2 = foo2(2) //这样指定参数名 调用
//函数参数 强制调用时指定参数名
func foo3(internalName internalName: Int)-> Int{
let local = internalName
return local
}
let result3 = foo3(internalName: 3) //这样指定参数名 调用
//property observers 属性监视器
var someProperty: Int = 43{
willSet{
print("old is \(someProperty),new is \(newValue)")
}
didSet{
print("now is \(someProperty),old is \(oldValue)")
}
}
someProperty = 33
//Lazy Initialization 惰性初始化
// 只能用于var 不能用于let 因为let的值在类创建时初始化完毕
// 当这个变量被用到时,才真正初始化
lazy var brain = CalculatorBrain()
//用匿名函数进行初始化
lazy var someProperty: Type = {
return <the constructed value>
}()
// 可失败的初始化 Failable init
init?(arg1:Type1,...){
//可以在这里返回 nil
}
// 例如 image 可能为nil
let image = UIImage(named: "")
// 可以这样判断
if let image = UIImage(named: ""){
print("ok")
}else{
print("no..")
}
// join数组
["2","3","4","5"].joinWithSeparator("&")
// casting 强制类型转换
let x = 1 as Double //强转成double
// 如果强转成功
if let x = (1.2 as? Int){
print("ok")
}else{ //失败
print("faile")
}
// 使用 is
if 1.2 is Double{
print("yes")
}else{
print("no")
}
// casting Arrays of AnyObject
var items:[AnyObject]
for item in items {
if let item- = item as? UIBarButtonItem {
// do something
}
}
for toolbarItem in toolbarItems as [UIBarButtonItem]{
// do something
}
let button:AnyObject
let title = (button ad UIButton).currentTitle
// 调用字类方法时的判断
let animal1: Animal = Dog() //animal 是dog的父类
// 但是 不能 animal1.jiao() animal1 上没有 jiao(叫)方法
// 得这样
if let dog_ = animal1 as? Dog { //尝试将animal1 转成 Dog
dog_.jiao()
}
// functon
var a = [1,2,3,4]
a += [2]
a.first
a.last
a.append(22)
a.insert(55, atIndex: 0)
a.insertContentsOf([91,92,93], at: 2)
a.removeAtIndex(1)
a.removeRange(0...3)
a.replaceRange(0...1, with: [101,102])
// map方法
var sA = a.map{"\($0)"}
// reduce 方法
var rA = a.reduce(0) { $0+$1 }
// Type Concersion 类型转换
var i = Int(36.6)
// Assertions 断言
assert(validation()!=nil, "the validation funtion returned nil")
// 转成NSString 获取length属性
let x = "123abc"
let l = (x as NSString).length
// 转成NSArray 调用其cjbs 方法
var a = [1,2,3]
var x = (a as NSArray).componentsJoinedByString("_")
// NSUserDefaults 用户持久化存储 可以存 “settings”
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject([1,2,3], forKey: "index1")
// 同步到硬盘
defaults.synchronize()
// UIView 只有一个superview 和一个subview数组 subviews
// 什么button lable 什么的都是UIView的子类
// UIWindow 是UIView的子类 : 处在最顶层
addSubView(aView:UIView) //添加一个view
removeFromSuperview() // 移除view
contentScaleFactor // 每个点有几个像素
// 在坐标系统中要使用CGFLoat 替代 Double Float...
// CGPoint
var point = CGPoint(x: 37.0, y: 55.2)
point.x -= 30
point.y += 20.0
// CGSize
var size = CGSize(width: 100.0, height: 50.0)
size.width += 42.5
size.height -= 11
// CGRect
struct CGRect{
var origin: CGPoint
var size: CGSize
}
let rect = CGRect(origin: aCGPoint, size: aCGSize)
// CGRect 的几个属性
var minX:CGFloat // 左边缘
var midY:CGFloat //y轴的中点
@IBDesignable // <- 在storyboard中绘制 这个UIView的子类
class FaceView: UIView {
@IBInspectable // <- 在右侧的inspetor中可以设置这些属性
// 就像设置button的各个属性
// 这里得明确指明变量的类型 才能正常显示
var color:UIColor = UIColor.blueColor(){ //笑脸线条的颜色
// 设置新值时请求重绘
didSet{
setNeedsDisplay()
}
}
}
// Extensions 可以给 类 结构 枚举 增加属性和方法(即使没有源码)
// 只能增加方法 不能覆盖
// 不能增加存储属性 即:只能增加计算属性
// Protocols
// A way to express an API minimally
// 只指定需要的属性和方法
// 协议也只是一种类型,除了:没有存储 和 实现
// 协议可以被 class enum struct 实现
// 协议可以用来作为声明变量时的类型
// from https://github.com/vandadnp/swift-weekly/blob/master/issue11/README.md#inline
@inline(never) // 声明这个函数never编译成inline的形式
@inline(__always) // 生命这个函数总是编译成inline的形式
inline函数可以用 闭包 的形式实现
// 在这里 限定Type1 是user类型 还可以给它添加更多限制
class User{}
func testGo<Type1: User> (a1:Type1,a2:Type1)->Int{
return 0
}
var user1 = User()
var user2 = User()
var r = testGo(user1, a2: user2)
print(r)
// inout关键字传引用
func go(inout a:Int){
a+=1
}
var s = 0
go(&s)
//s = 1
// 外部参数名_(可省略) 内部参数名v https://www.natashatherobot.com/swift-init-with-_/
init(_ v: UInt32)
// 在闭包中 这样声明一个弱指针
{ [unowned self] in
x = x + 1
self.show(x)
}
// 尾随闭包写法
{(action:UIAlertAction) -> Void in
}
// 注意这个闭包的写法
alert.addTextFieldWithConfigurationHandler {
(textField) in
textField.placeholder = "导航系统密码!"
}
b:String? //这样声明的话
b!.xx // 这里得unwrap
b!.yy
a:String! //这种类型是Optional 这种类型使用时可以省略unwrap符
a.xx
a.yy // 可以这样用 省略unwrap
// class var
private extension UIColor {
// class var 跟 static var相似
// 用class修饰的可以被子类改变
class var random:UIColor {
// ...
}
}
// 初始化实例阶段不能应用实例的属性
class DropitViewController: UIViewController,UIDynamicAnimatorDelegate {
// 显示所有内容的View
@IBOutlet weak var gameView: BeizePathView!
// 这样初始化的时候会有问题
// var animator = UIDynamicAnimator(referenceView: gameView)
// 这行代码执行在初始化阶段 不能引用实例的属性 等实例初始化完成后才能引用实例的属性
// 一种方法是:在这里设成nil 在viewDidLoad 中执行初始化
// 另一种是: 将属性设成lazy 并用闭包初始化它
lazy var animator:UIDynamicAnimator
/*这个类型必须制定,估计是:使用闭包进行初始化时,不能使用类型推断 要指定其类型*/
= {
let $ = UIDynamicAnimator(referenceView: self.gameView)
$.delegate = self
return $
}()
}