swift学习 (数据类型+函数和闭包)

无意间看到自己以前学习swift的笔记,从近两年苹果的发布会,可以看出苹果推动swift的决心,OC更换为swift也是未来发展的趋势,想起当初自己钻研学习swift的痛苦的情景,现在把它们整理出来并与现在最新的swift结合以供初学者使用,让初学者少走弯路。有时间会陆续整理后面知识的学习笔记。


字符串

字符串介绍
  • String 是一个结构体
  • String 的性能比 NSString 的性能要高
  • String 目前具有了绝大多数 NSString 的功能
  • String 和 NSString 可以无缝转换
  • 在 Swift 中绝大多数的情况下,推荐使用 String 类型
字符串定义
  • 用 var 定义一个可变字符串
  • 用 let 定义一个不可变的字符串

//定义一个空的字符串

let str = ""
let str1 = String()

//定义字符串并赋初值

let str3 = "hello world"

//用 var 定义可变字符串,用 let 定义不可变字符串

var mutableStr = "string can be changed"

//删除第一个字符 s

mutableStr.remove(at: mutableStr.startIndex)
print(mutableStr)
字符串拼接

字符串拼接可以真接用加号
//: 字符串拼接

let ustr = "hello, world"
let ustr2 = "I hove you"

//连接字符串可以直接用 + 和 +=

var ustr3 = ustr + ustr2
ustr3 += "very good"

//如果拼接的字符串为可选值

var ostr: String?
ustr3 += ostr ?? "no value"

//字符串和变量拼接

var name = "老王"
let str6 = "他正准备打开家门,发现 \\(name)从里面出来了"

//: 字符串的格式化
//妈妈再也不用担心我用 stringWithFormat

let strb = "字符串\(stra)连接整型\(a)和浮点型\(f)"
var h = 5
var m = 6
var s = 3
let time = String(format: "%02d:%02d:%02d", h, m , s)
let time1 = String(format: "%02d:%02d:%02d",arguments: [h, m , s])
字符串比较

swift 中用 == 和 != 来比较两个字符串
oc 中用 equalToString 来比较两个字符串
//比较字符串

let cstr = "hello"
let cstr2 = "world"
let cstr3 = "hello"
if cstr == cstr3 {
print("相等")
}
if cstr2 != cstr3 {
print("不相等")
}
判断前后缀
var str7 = "ni hao ma"
let count = str7.utf8.count
let prefix = str7.hasPrefix("ni")
let suffix = str7.hasSuffix("ma")

数组

//数组的创建
//用var创建一个可变的数组, 用let创建一个不可变的数组

var array = ["dog", "cat", "pig"]
var emptyArr: [String] = []
array.append("fish")

//用初始化的方式, 来创建数组, 一定要指定类型

var array2: [String] = Array()

//数组的遍历

for item in array {
print(item)
}

//遍历同时拿到index

for item in array.enumerated() {
print("\(item.offset): \(item.element)")

}

//倒序遍历

for item in array.reversed() {
print(item)
}

//数组的操作
//数组的合并

var array3 = ["goat", "snake"]
var array4 = ["dog", "cat", "pig"]
var array5 = array3 + array4

//删除元素

let removed = array5.remove(at: 0)

//修改

array5[0] = "sheep"

//和oc的数组互转

let ocArray = array5 as NSArray
ocArray.subarray(with: NSMakeRange(0, 3))

字典

//定义一个字典
//用var定义一个可变的字典, 用let定义一个不可变的字典

var dict = ["first": "dog", "second": "cat"]

//定义一个空的字典

var dict1: [String: String] = Dictionary()
var dict2: [String: String] = [:]

//遍历字典

for (k, v) in dict {
print("key: \(k), value: \(v)")
}

//字典的操作, 增删查改, 字典的操作都是围绕key值做操作

//增

dict["third"] = "pig"

//删

dict["second"] = nil

//查:从字典中取出的值,是一个可选值, 使用的时候最好做一次可选绑定

let first = dict["first"]

//改

dict["first"] = "duck"
print(dict)

函数

//用func创建一个函数
//函数名后面接小括号, 小括号不能省略
//小括号里面放参数, 参数必须指定类型, 多个参数用逗号隔开
//如果没有返回值, 返回值的部分可以省略

func add(a: Int, b: Int) -> Int {
return a + b
}

//函数没有返回值,本质上返回一个空的元组

func addOne(a: Int, b: Int) {
print(a + b)
}

func addTwo(a: Int, b: Int) -> () {
print(a + b)
}

func addThree(a: Int, b: Int) -> Void {
print(a + b)
}

//没有参数,没有返回值

func methodOne () {
print("hello, class seven")
}

methodOne()

//有参数, 没有返回值
func methodTwo (a: Int, b: Int) {
print(a + b)
}
methodTwo(a: 5, b: 5)
//有参数有返回值, 返回的值和返回值类型必须保持一至

func methodThree (a: Int, b: Int) -> Int {
return a + b
}

let result = methodThree(a: 5, b: 5)

let method = methodTwo

函数的参数

//默认情况下, swift会给每个参数加一个和形参一样的外部参数名
//外部参数名, 就是对参数做解释说明的字符串
//外部参数名, 在调用的时候, 必须写

func add(a: Int, b: Int) -> Int {
return a + b
}

add(a: 5, b: 10)

//也可以自定义外部参数名

func addOne(first a: Int,second b: Int) -> Int {
return a + b
}
addOne(first: 5, second: 10)

//也可以忽略外部参数名
//使用忽略运算符忽略外部参数名

func addTwo(_ a: Int,_ b: Int) -> Int {
return a + b
}
addTwo(5, 10)

函数的默认参数

//swift语言函数的参数可以设默认值
//如果参数有默认值,则该参数可传可不传

func add(a: Int, b: Int = 10) -> Int {
return a + b
}

add(a: 5)
add(a: 5, b: 156)

 func customLabel (title: String, fontSize: CGFloat = 13,   alignment: NSTextAlignment = .left, numerOfLines: Int = 0) -> UILabel {
let label = UILabel()
label.text = title
label.font = UIFont.systemFont(ofSize: fontSize)
label.textAlignment = alignment
label.numberOfLines = numerOfLines

    return label
}

let label0 = customLabel(title: "label", fontSize: 13, alignment: .left, numerOfLines: 0)

let lable = customLabel(title: "label")

闭包

//闭包是一个匿名的函数块
//闭包被完整地包裹在大括号里面
//闭包的调用方式和函数一样
//闭包可以做为参数传递,也可以做为返回值返回

//没有参数,没有返回值

func methodOne () {
print("hello, class seven")
}

methodOne()

//有参数, 没有返回值

func methodTwo (a: Int, b: Int) {
print(a + b)
}
methodTwo(a: 5, b: 5)
//有参数有返回值, 返回的值和返回值类型必须保持一至
func methodThree (a: Int, b: Int) -> Int {
return a + b
}    
闭包的定义和调用
//没有参数,没有返回值的闭包
let clousureOne = {
print("hello, class seven, seven")
}

clousureOne()

 //有参数, 没有返回值
//参数和执行语句都写在大括号里面, 用in隔开
//闭包没有外部参数名
let clousureTwo = {
(a: Int, b: Int) in
print(a + b)
}

clousureTwo(5, 12)

//有参数, 有返回值
let clousureThree = {
(a: Int, b: Int) -> Int in
return a + b
}

let result = clousureThree(5, 240)

闭包的使用

需求::

下载一部 av, 完成后更新 UI 提示, 要求用闭包实现
实现::

  1. 新建一个函数,实现下载的功能
  2. 新建一个闭包,更新 ui
  3. 将闭包作为函数传递,下载成功后,下载函数中调用更新 UI 的闭包,功能实现

class ViewController: UIViewController {

var activity: UIActivityIndicatorView?

override func viewDidLoad() {
    super.viewDidLoad()

    let label = UILabel(frame: CGRect(x: 20, y: 40, width: 400, height: 30))
    self.view.addSubview(label)

    activity = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
    self.view.addSubview(activity!)
    activity!.center = self.view.center

    let downloadAVFinished = {
        (money:  String) in
        print(money)
        label.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
    }

    dowloadAV(downloadAVFinished)

    activity!.startAnimating()
}

func dowloadAV (block: (String)->()) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in

        let time: NSTimeInterval = 3
        let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(time*Double(NSEC_PER_SEC)))
        dispatch_after(delay, dispatch_get_main_queue()) { () -> Void in
            let av = "苍井空"
            block(av)
            self.activity!.stopAnimating()
        }
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

尾随闭包

  • 如果闭包代码块作为函数的最后一个参数
  • 当函数调用时,可以将闭包代码块写在参数的小括号的外面
  • 尾随闭包可以增强函数的可读性
  • 注意: 如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉。
//定义一个闭包
let closure = {
(a: Int) -> Int in 
return a + 5
}

    //定义一个函数,第二个参数为闭包
func method (a: Int, sum: (Int)->(Int))->Int{
return sum(a)    
}

//调用函数
func(5, closure)

//上面的调用等同于,直接将闭包代码块作为参数传入
func(5, {
(a: Int) -> Int in 
return a + 5
})

//将闭包写在括号外面
func (5){
(a: Int) -> Int in 
return a + 5
}

闭包的循环引用

循环引用的场景
  • 当 self 中强引用了闭包,而闭包中又使用了 self 时,会发生循环引用
  • 循环引用的三种解决方法
  1. 使用 oc 的 weakself 的写法
    weak 的对象在运行时,有可能被设为 nil, 所以只能用 var, 且是可选的
    weak var weakself = self
    downloadBlock = {
    (money: String) in
    print(money)
    weakself!.textLabel!.text = "我下载了了(money)rmvb,快来和我做朋友吧"
    print("======(self)")
    }

2.使用 swfit 的 weakself 的写法
[weak self] 表示闭包中的 self 是弱引用,在运行时可能被设为 nil,所以闭包中的 self 也是可选的

    downloadBlock = {
        [weak self] (money:  String) in
        print(money)
        self!.textLabel!.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
        print("======\(self)")

3.使用 swift 中的 unknown
[unowned self] 和弱引用不同的是,unowned 引用是永远有值的。因此,unowned 总是被定义为不可选;
如果 self 释放,会产生野指针
使用的情况是 self 永远不需要释放

    downloadBlock = {
        [weak self] (money:  String) in
        print(money)
        self!.textLabel!.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
        print("======\(self)")
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容