您的位置:首页 > 移动开发 > Swift

读书笔记-《Swift语言实战入门》-语法部分

2015-07-06 16:21 716 查看
《Swift语言实战入门》人民邮电出版社

写在前面:

       之前一直在学习web的东西,怎么突然跑来学Swift,说到底是为了生存。

       在Web技术非常成熟的今天,也许对于一个毕业生来说,要成为一个优秀的前端工程师不是那么容易的。至于我本人,不是学霸也不是技术大牛,对技术研究也没有非常浓厚的兴趣,但能做各种新奇的互联网产品还是挺让人兴奋的。另一方面,通过编写APP也可以验证自己的一些想法,而且开发过H5的移动应用以后,发觉原生的应用还是质量更高一些。用H5确实可以实现很多原生的效果和功能,配以phonegap等框架就很好用了,可是这本来就是吃力不讨好的事情。

       于是,为了明天还能正常上班,同时应社会潮流,来学习swift。

       大学时候读书不用功,C++学了那么点现在连指针都忘了,一直说Objective-C学习曲线比较陡,对于用脚本语言的我来说似乎更陡。

       幸好有swift出现,而且相信苹果以后也会继续发展这门语言,尽管目前还有很多应用都是用Objective-C 来写的,但swift还是大有前途的。

       接下来,要恶补一下关于C的东西了。

2015.7.6
------------------------------------------------------------------------------------------------------------------------------------------------------------

基础语法

    大小写敏感

    字符串必须用双引号包裹

    let - 定义常量

    var - 定义变量

    swift是强类型语言,并且拥有“类型推断”机制

var str = "Hello, World!" // 自动推断为String类型
var tmp:int // 冒号后面指定数据类型


    整型

        有符号整型 - Int Int8 Int16 Int32 Int64(系统是32位的话就默认Int32,64的位的话就默认Int64)

        无符号整型 - UInt UInt8 UInt16 UInt32 UInt64(同上,可以显示的最大值比有符号要多一倍)

    浮点型

        Float - 32位

        Double - 64位(使用类型推断时默认为Double)

    布尔型

        Bool - 只有true和false两个可能值

    字符串

        String - 不能直接将字符串当做字符数组,需要使用String.Index来访问指定Index的字符

        无论何时,传递的都是值的拷贝

var tmp = "Vincent"
println("你好,\(tmp)") // 通过使用\(变量)来将变量转换成字符串后输出


    字符

        Character - 一个Unicode字符

    字符串操作

        相加 - 用+号

        相等 - 用 == 

        判断前缀 - .hasPrefix()

        判断后缀 - .hasSuffix()

        大小写 - .uppercaseString / .lowercaseString

    输出字符串

        print、println、NSLog等

    值类型和引用类型

        值类型 - 修改一个变量,另一个变量不会被改变

        引用类型 - 修改一个变量,另一个变量会改变

    可选类型

        Optional - 当变量有值时返回值,没有值时返回nil

var roundValue:Int? // 在类型后面添加一个问号
var optionValue:Optional<Int> // 显式调用
       强制解析可选 - 在可选变量名后加!,强制获取变量的值

var a:Int? = 8
println(a!) // 省去判断a是否有值的步骤
        隐式解析可选 - 同样直接访问变量的值,但当变量没有值时依然会报错(没什么用)

var a:Int! = 8
println(a)
  nil
        在Objective-C中nil代表一个指向不存在对象的指针,在swift中表示空的关键字为nil,没有其他含义

        nil不能用于非可选的常量或变量,如果会出现没有值的情况,务必将变量或常量声明为可选类型

   可选运算符

        ?? - 当第一个变量没有值时取第二个变量的值

var a:Int?
var b = 1
var c = a ?? b // c等于1,因为a没有值
    元组(相当于关联数组)

var (a,b) = (1,2) // 可以直接访问a,b
var a = (b:1, c:2) // 通过a.b或者a.0访问b
    类型别名
        使用typealias关键字,给已有类型名称取一个别名,同一个工程中不能出现重复的别名

typealias ShortInteger = Int8
ShortInteger.max // 127
    类型转换
        Int(12.4)

        并非所有类型可以互相转换

        浮点数转换成整型值时,浮点数都会被截断,只保留整数部分

    断言

        assert(condition, message)

    溢出运算符

        &+ - 溢出加法

var intMaxNum = UInt8.max
intMaxNum = intMaxNum &+ 1 // 输出0,被截断

        &- - 溢出减法

var intMinNum = UInt8.min
intMinNum = intMinNum &- 1 // 输出255


        &* - 溢出乘法

        &/ - 溢出除法

        &% - 溢出求余

        溢出除法和溢出求余都是针对除数或求余数为0的情况进行截断

    数组

        常量数组或变量数组

var arr = [String]()
arr.append("a")
arr.insert("b", atIndex: 0)
arr+=["c"]
arr.isEmpty
arr.count
arr.removeAtIndex(2)
arr.removeLast()
arr.removeAll()
        字典
var arr = ["food":"apple"]
arr.keys
arr.values
arr.updateValue("bear", forKey: "food")
arr.removeValueForKey(key)
    结构
struct{
var ID = 0
var Name = "Vincent"
}
    枚举
enum EnumeType{
case A, B, C = 5, D // A,B等于, C为5, D为6
}
    switch语句值绑定
var Point = (2, 0)
switch Point{
case (var x, 0): x--
case let (x, y): println("\(x), \(y)")
}
    for in 循环
// 当不需要使用范围内每一项的值时,可以使用下划线"_"来忽略对值的访问
var arr = [1,2,3,4,5,6,7,8]
var index = 0
for _ in arr {
index++
}

    函数

func isSell(productName:String) -> Bool {
var selled:Bool = false
return selled
}
    定义了返回值的函数必须在函数体中设置返回值
    返回值可以由多个值组成的复合返回值

func test() -> (Int,Bool) {
let a = 10
let b = false
return (a, b)
}
    使用外部形参可以使函数表达意图更明确
func printInfo(sname:String, ssex:String) -> String{
return "Name is "+sname+" and sex is "+ssex+"."
}
printInfo("Vincent", "male")

    闭包

        swift三种闭包形式: 全局函数、子嵌套函数、匿名体函数

        函数作为一种闭包

var names = ["Vincent", "Katty", "Jack"]
var sortArray = names.sort(compareName)
func compareName(s1:String, s2:String) -> Bool {
return
f56b
s1 < s2
}
        直接写在函数参数中

var sortArray = names.sort({
(s1:String, s2:String) -> Bool in return s1 > s2
})
        省略return关键字
var sortArray = sort(names, {s1, s2 in s1 > s2}) // 忽略return,默认返回表达式结果
        省略参数类型和参数
var sortArray = sort(names, {$0 > $1}) // 忽略参数类型,则要省略in关键字
        最简方案

var sortArray = names.sorted(>) // 因为swift定义了> <比较函数,因此可以忽略参数
        trailing闭包(尾随闭包)

var sortArray = sort(names) { $0 > $1 } // 本身用途在于当闭包很长时,为增加代码可读性,闭包可以写在()之外,函数默认把闭包当做最后一个参数
        闭包是引用类型,因此将函数/闭包赋值给一个常量或者变量,都是引用,赋给两个不同的变量或者常量时,指向同一个闭包

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

面向对象编程

    温故知新:封装、继承、多态

    属性观察者

        当属性变化时,就会被调用该方法,但属性初始化时不会调用

<pre name="code" class="objc">var score:Int = 0{
willSet{
// 分数变化,标签内容也要变化
label.text = "\(newValue)"
}
}



        willSet - 可带newName参数,默认newValue

        didSet - 可带oldName参数,默认oldValue

        上述可改成

var score:Int = 0{
willSet{
// 分数变化,标签内容也要变化
label.text = "\(newValue)"
}
}
    初始化方法 - init()

    反初始化方法 - deinit()

    类与结构体的区别:

        1.在数据结构的扩展和继承方面,类更加强大

        2.类可以通过反初始化来释放存储空间,而结构体不行

        3.类的对象是引用类型,结构体是值类型

    创建结构的条件:

        1.结构主要是用来封装一些简单的数据值的

        2.当赋值或者传递的时候更希望这些封装的数据被复制,而不是被引用过去

        3.所有被结构存储的属性本身也是数值类型

        4.结构不需要被另外一个类型集成或者完成其他行为

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Swift语言语法高级特性

    继承

class living{}
class animal:living{}
class cat:animal{}
        使用super关键字来访问父类的方法

        通过final关键字定义的方法和属性不能被重写

    多态


        注意:重载与重写的区别:重载是同一个类中实现了多个同名的方法(参数或返回值不同),重写是子类中实现与父类中相同名称和返回值的方法

    封装

        目的:1.使用数据更方便;2.保护数据

        权限修饰关键字:private、internal、public

    类的拓展

/*为Double类拓展一个方法mm,关键字extension*/
extension Double
{
func mm()->String
{
return "\(self/1)mm"
}
}
    协议

        等同于其他语言中的接口,关键字是protocol

        协议可继承于另一协议,但不能继承于类,因为协议中不能有方法的具体实现

    类组合

        优先使用对象组合,而不是类继承

        swift中继承是单继承,并不支持多继承

        可以理解为,继承了一个类,然后属性中存在另一个类的对象

    泛型

        参数可以是多个类型

func swapT<T>(inout a:T, inout b:T)
{
var tmp = a
a = b
b = temp
}

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Swift操作Cocoa底层库

    IOS开发体系

        Core Os

        Core Service

            Core Data - 数据模型、数据存储

            Foundation - 字符串、数值管理、容器及枚举等与其他图形用户界面没有直接关系的功能

        Media

            Core Graphics - 处理本地2D向量渲染和图片渲染

            Core Animation - 动画视图及其他内容提供更高级别支持

            OpenGL ES - 为使用硬件加速接口的2D和3D渲染提供支持

        Cocoa Touch

            UIKit - 用户界面工具包

    Swift与Foundation框架

        NSString

            stringByReplacingOccurrencesOfString - 替换字符串

var string = "hello world"
string.stringByReplacingOccurrencesOfString("world", withString: "swift")
            lowercaseString - 转换成小写

            componentsSeparatedByString - 将字符串拆分成数组

let string:NSString = "Apple,iOS,Swift,String"
let subStringArray = string.componentsSeparatedByString(",")
            componentsSeparatedByCharactersInSet - 将字符串拆分成数组,根据集合中的字符

let String:NSString = "Apple,iOS;Swift;String"
let subStringArray = string.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString:",;"))
            substringFromIndex(index) - 从index到末尾

            sustringToIndex(index) - 从头到index

            substringWithRange(nsRange) - 获取nsRange指定的子串

            rangeOfString - 查找字符串,有则返回NSRange类型的结构体,没有则返回NSNotFound

                可选option:NSStringCompareOptions.BackwardsSearch(倒序查找)、NSStringCompareOptionsCaseInsensitiveSearch(不区分大小写)

        NSNumber

            转换成swift类型:

let boolV:NSNumber = true
let bool = boolV.boolValue
let intV:NSNumber = 1
let int = intV.intValue
        NSArray

            NSArray - 静态数组 NSMutableArray - 动态数组

            removeLastObject - 删除最后一个元素,只有动态数组可以

            .count - 获取数组长度

            .firstObj - 第一个元素 .first(swift)

            .lastObj - 最后一个元素 .last(swift)

            objectAtIndexs(indexSet : NSIndexSet) - 获取指定索引的元素数组集合    (swiftArray[1...2])

            containsObject(value) - 判断数组中是否存在元素,返回true/false    (contains(swiftArray, 4))

            indexOfObject(value) - 查处数组中该元素的位置,有则返回下标,没有则返回NSNotFound      (find(swiftArray, 4))

        NSSet

            NSSet - 静态集 NSMutableSet - 动态集

            .allObject - 获取所有元素

            .isSubsetOfSet() - 是否子集

            .intersectsSet() - 是否有交集

            .isEqualToSet() - 是否相等(可以用 == 判断)

            集操作(必须是动态集)

            .intersectSet() - 交集

            .unionSet() - 并集

            .minusSet() - 补集

            .countForObject() - 计算集中元素的添加次数,每个集中不会重复出现一个元素,但可以记录添加次数(例如统计词频)

        NSData

            NSData - 静态数据 NSMutableData - 动态数据

let string = "hello world"
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
// 编码类型 - NSUTF8StringEncoding, NSUnicodeStringEncoding, NSASCIISrtingEncoding等
// allowLossyConversion - 转换过程中是否允许字符进行必要的删减或者替换
            其他初始化方法

// 字符串
let data = NSData(data: utf8EncodeData!)
// URL
let url = NSURL(string:"https://www.baidu.com")
let data = NSData(contentsOfURL:url)
// 文件
let filePath = NSBundle.mainBundle().pathForResource("test", ofType:"txt")
let data = NSData(contentsOfFile: filePath)
            .description - NSData对象的描述内容(十六进制编码)

            .bytes - NSData对象内容的Byte数组指针,用length来获取数据字节数组的长度

// NSData转换成NSString
var bytes = utf8EncodeData.bytes
var stringFromData = NSString(bytes: bytes, length: utf8EncodeData.length, encoding: NSUTF8StringEncoding)
            
// NSData与Base64编码字符串相互转换
// 转换成Base64编码字符串
let base64string = nsdata.base64EncodingString WithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
// 解码
let base64data = NSData(base64EncodingString:base64EncodingString, options:NSDataBase64DecodingOptions.fromRaw(0)!)
let base64String = NSString(data: base64data, encoding: NSUTF8StringEncoding)
            .writeToFIle(path, atomically: Bool) -> Bool - 将数据写入指定路径的文件内,atomically为true代表先写入一个备份文件,防止异常导致数据损坏

            .writeToURL(url:NSURL!, atomically: Bool) -> Bool

            动态数据

            NSMutaleData(capacity:Int) - 初始化时指定空间大小

            NSMutableData(length:Int) - 初始化时分配归零字节

            .increaseLengthBy(_extraLength: Int) - 修改数据对象的长度

                如果设置长度大于现有,用归零字节填充;如果小于现有,则抛弃超出的部分

        文件操作

            使用iOS设备的用户不能直接访问它的文件系统,每个应用拥有独立的文件空间,一个应用只可以访问本应用分配的文件目录,不可以访问其他目录,这个目录称为沙箱。

            沙箱包含Bundle Container(App程序文件)、Data Container(运行程序产生的文件)、iCloud Container(数据云同步)

            应用目录结构

                MyApp.app - 应用的运行包bundle,目录只读,并进行了签名,安装后如对该目录进行任何写操作都会改变目录的签名内容,使得应用无法启动,该应用本身能获得bundle中的任何文件的读权限

                Documents - 存储用户产生的内容,建议将用户可操作的文件数据都放到该目录,该目录下的所有文件都可以通过iTunes进行备份或恢复

                Documents/Inbox - 用于访问被外部应用锁清秋当前应用打开的文件,例如应用A请求MyApp打开read.doc,系统会先将read.doc拷贝到MyApp的Documen/Inbox目录下,MyApp有读和删权限,但不能新建以及对已有文件进行写入。要编辑的话要先移动到其他目录

                Library - 存储非用户数据,可自己创建子目录,常用子目录有Application Support、Caches。前者放置配置文件、模板、数据文件等应用在运行中用户相关,但又希望用户不可见的文件;后者用来存放缓存文件,存放时间比tmp长。该目录下除Caches外,其他都可以通过iTunes进行备份

                tmp - 存放临时文件,应用不运行时系统可能会对该目录下的内容进行清理,该目录内容不会通过iTunes进行备份

            访问文件

                可以用string和NSURL(官方建议)来描述文件路径

                NSTemporaryDirectory() - 返回应用临时文件目录

                NSSearchPathForDirectoriesInDomains(_directory: NSSearchPathDirectory.DocumentDIrectory, _domainMask: NSSearchPathDomainMask.UserDomainMask, true) -> AnyObject[]! - 返回满足条件的文件目录

                    NSSearchPathDirectory: (搜索目录)

                        ApplicationDirectory - /Application

                        LibraryDirectory - /Library

                        DocumentDirectory - /Documents

                        ApplicationSupportDirectory - Library/Application Support

                        UserDirectory - /Users

                        CachesDirectory - Library/Caches

                    NSSearchPathDomainMask: (搜索的域)

                        UserDomainMask - 用户域,指向当前用户的home目录

                        LocalDomainMask - 本地域,指向对所有用户可用的当前机器范围

                        NetWorkDomainMask - 网络域,指向/NetWork

                        SystemDomainMask - 系统域,指向/System

        NSURL

            创建NSURL对象

NSURL(scheme:"http", host:"swiftnaction.com", path:"/sayhello/toChinese")
NSURL(scheme:"file", host:nil, path:"/sayhello/toChinese") // 本地

let baseURL = NSURL(string: "file:///path/to/web_root/")
let url = NSURL(string:"folder/file.html", relativeToURL: baseURL) // 相对于baseURL
通过.absoluteURL来获得绝对路径

let path = NSURL.fileURLWithPath("/sayHello", isDirectory: true) // path值为'file///sayHello/, isDirectory为true时指定URL为一个目录
            获取URL指定部分

                url.host - 域名  url.scheme - 协议名  url.port - 端口  url.query - 参数名  url.fragment - 值

                url.lastPathComponent - 路径最后内容  url.path - 路径  url.pathComponents - 将路径内容划分成数组  url.relativePath - 相对路径

                url.absolutePath - 绝对路径  url.pathExtension - 路径文件名后缀  url.user - 用户名  url.password - 密码

            文件URL

                fileURL.checkResourceIsReachableAndReturnError(nil) - 判断文件是否可达,仅可以判断本地资源,网络资源全返回false

                .fileURL - 判断路径是否为文件路径,URL的scheme为file类型,就返回true,否则返回false

            文件URL路径拼接

                URLByAppendingPathComponent(_pathComponent: String!,  isDirectory: isDirectory:Bool) -> NSURL! - 追加路径到当前路径末尾

                URLByAppendingPathExtension(_extension: String!) -> NSURL! - 追加后缀名到末尾,如果是末尾是目录,则加到目录名称后面

                .URLByDeletingLastPathComponent - 删除最后路径内容

                .URLByDeletingPathExtension - 删除最后路径后缀名

            NSURLComponent(只支持iOS7.0以上的API)

                与NSURL的区别就是可以对URL的各个部分进行读写,属性名基本相同

                获取URL-Encoded格式属性值:.percentEncodedHost (加上percentEncode)

        NSFileManager

            通常使用NSFileManager的共享实例defaultManager()来处理文件操作

            路径查询

                .contentsOfDirectoryAtPath() 浅搜索

                .contentsOfDirectoryAtURL() 浅搜索,根据URL

                .enumratorAtPath() 深度搜索

                .enumratorAtURL() 深度搜索,根据URL

                .subpathAtPath() 查找目录下的所有子路径

            路径操作

                .fileExistAtPath() 判断是否存在文件

                createDirectoryAtURL(url, createIntermediates, attributes) 创建目录,如果createIntermediates为true,则当路径指定目录中父目录不存在,就创建相应父目录,否则父目录不存在就返回false,创建失败

                createFileAtPath(path, contents:NSData!, attributes) 创建文件

                copyItemAtURL(srcURL, dstURL) 拷贝文件到路径

                removeItemAtURL(toURL) 删除文件

                moveItemAtURL(srcURL, toURL) 移动文件,文件已存在则返回false

            文件访问权限

                displayNameAtPath(path) 显示本地化显示名

                isReadableFileAtPath() 判断是否有读权限

                isWritableFileAtPath() 判断是否有写权限

                isExecutableFIleAtPath() 判断是否有执行权限

                isDeletableFileAtPath() 判断是否有删除权限

                attributesOfItemAtPath() 返回指定路径的各种属性

                cotentsAtPath() 返回指定路径文件的内容数据,如果指定路径为目录,则返回nil

                contentsEqualAtPath(path1, path2) 比较两路径内容是否相等

        NSFileHandle

            定位

                .offsetInFile 获取当前文件句柄的活动指针偏移量

                seekToEndOfFile 将指针指向文件末尾,并返回移动后的指针偏移量

                seekToFileOffset(_offset: UInt64) 将指针移动到指定的偏移量位置

            文件数据读取

                第一步,获取文件句柄 NSFileHandle.fileHandleForReadingFromURL() 如果文件不存在,则返回nil,成功则指向文件开头,偏移量为0

                第二步,定位偏移量

                第三步,指定读取数据长度读取:readDataOfLength(length: Int) 读取到尾部 readDataToEndOfFile()

            文件数据写入

                writeData()

        NSBundle

            NSBundle.mainBundle() 获取当前应用可执行文件的目录位置,对于App来说,通常指向xxx.app/这个根目录

            .bundleURL .bundlePath

            获取bundle信息

                应用程序bundle配置信息一般存在Info.plist中

                mainBundle.bundleIdentifier 应用程序唯一标示包名

                mainBundle.infoDictionary 应用程序Info.plist词典对象实例

                mainBundle.objectForInfoDictionaryKey("CFBundleName") 获取bundle词典中的属性值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  swift