No1 Swift语法简介

一 常量和变量

  • 基本使用
    • var 定义变量,设置之后可以修改
    • let 定义常量,设置之后不可以修改
    • 语句末尾不用使用 ;
    • 在 Swift 中使用 print() 替代 OC 中的 NSLog
    • print 的性能更好,后面会演示
// 定义变量
var i = 10
print(i)
i = 15
print(i)

let j = 20
// 常量一经定义不能自改数值
//        j = 25
print(j)

注意点: 在Swift开发中, 一般情况下先用let, 只要需要修改数据时才用var, 使用let的好处, 可以避免数据被修改, 可以保证数据安全性

  • 类型推导:

    • Swift中如果在定义变量/常量时进行初始化, 那么数据类型可以不用写, 系统会自动根据右边的复制推导出变量/常量的类型
    • Swift开发中能不写数据类型就不写数据类型, 尽量使用编译器的自动推导
    • 只有当我们需要明确的指定数据的长度, 获取需要先定义再初始化时才明确的指定数据类型
    • 使用自动类型推导好处: 大大降低代码中的冗余代码
  • 类型转换:

    • OC中有显示转换和隐式转换 double value = 10.1 + 9
    • Swift中只有显示转换没有隐式转换, 也就是说只有相同类型的数据才能进行赋值和计算
let x = 10
let y = 10.5
let z: Double = 20

print(Double(x) + y)
print(x + Int(y))
print(y + z)
  • 如果要显式的指定变量的类型,可以定义使用:var 变量名: 类型 = 值

二 元祖

  • 元祖定义
    • 复合数据类型
    • 只要将多个相同或者不同的数据用()括起来就是元祖
    • 优点: 在以前没有元祖之前C和OC语言是通过传入指针或者返回结构体的方式来返回多个值的, 而有了元祖之后就可以实现让一个函数返回多个值
let number3: (Int, Double, Int, Double) = (10, 10.1, 9, 44.40)
number3.0
number3.1
number3.2
number3.3

三 逻辑分支

  • if判断语句
    • Swift 中没有 C 语言中的非零即真概念
    • 在逻辑判断时必须显示地指明具体的判断条件
    • if 语句条件的 () 可以省略
    • 但是 {} 不能省略
var i = 10

if i > 0 {
    print("OK")
}
  • 三目运算符
var a = 10
var b = 50

var result = a > b ? a : b
print(result)
  • switch
    • 大部分用法和OC一样
    • Swift中条件语句可以不用写()
    • OC中default可以省略, 而Swift中大部分情况不能省略
    • OC中default的位置可以随便写, 而Swift不可以
    • OC中每个case后面必须加上break, 否则会出现穿透, 而Swift不会穿透, 也就是说不用写break
    • OC中要在case中间定义变量必须加上{}, 否则作用域混乱, 而Swift不用
    • 可以判断区间和元祖

四 可选类型

  • 什么是可选类型
    • 一个变量可以有值也可以没有值, 我们就称之为可选类型
  • 在Swift中如果使用一个可选类型的变量/常量, 必须解包操作

    • 解包: 只需要在变量/常量后面加上 !
    • !含义: 代表告诉系统该变量/常量中一定有值, 如果强制解包一个没有值的常量/变量,那么会报错
  • 格式:

    • 修饰符 变量名称:Optional<数据类型>
    • 修饰符 变量名称: 数据类型?
  • 语法糖: 因为在Swift中可选类型用得非常非常多, 所以为了简化代码, Swift提供了一个语法糖, 可以用“? ”代替 Optional<数据类型>
let number: Optional<Int> = 10
print(number!)
let number2 = 10
let sum = number! + number2

可选类型注意点: 在开发中一般情况下尽量不要强制解包一个可选类型, 否则会引发错误

  • 防止上述情况,使用注意

    • 方法1 增加判断
    • 方法2 可选绑定
      • 如果url不为nil, 系统内部就会自动将解包之后的值赋值给temp, 并且只有temp有值时才会执行{}中的代码
    // Swift开发中推荐这种写法
    if let temp = url
    {
    let request = NSURLRequest(URL: temp)
    }

五 循环

  • 传统for
    • 基本用法和OC一致
    • for后面的()可以省略
    • for后面的{}不可用省略
    • Swift开发中不建议使用传统for循环
// Swift开发中推荐的for循环格式
for i in 0..<10
{
    print(i)
}
  • while循环
var number = 0
while number < 10
{
    print(number)
    number++
}
  • do while
    • 基本用法和OC一致
    • Swift2.0开始dowhile循环中没有do, 只有repeat, 因为do被作用异常处理
var index = 0
repeat{
    print(index)
    index++
}while index < 10

六 数组

  • 格式: var arr: Array<Int> / var arr: [Int]
  • 可变和不可变对应:var/let

  • 定义数组 简写为:var arr = [1, 2]

  • 1.遍历数组(取值)
 arr[0]
 for item in arr
 {
    print(item)
 }
  • 2.添加 arr.append(3)
  • 3.修改 arr[1] = 9
  • 4.删除 arr.removeAtIndex(0)
  • 5.合并
 var arr1 = [3, 5, 7]
 arr += arr1
  • 6.Swift特殊
for item in arr[0..<2]  // 0~1
{
    print(item)
}

七 字典

  • 格式:var dict: Dictionary<String, String>
  • 可变和不可变 var/let

    注意: 将OC的{}换成了[]

  • 企业开发中字典使用得最多的类型就是 [String: NSObject]类型
    var dict2 = ["name": "l
    s", "age": 30, "score": 99.9]

/// 定义并实例化字典
var dict = [String: AnyObject]()

dict["name"] = "zhangsan"
dict["age"] = 18
print(dict)

// 设置相同 key,之前的数值会被覆盖
dict["name"] = "lisi"
print(dict)

// 删除某一个 key
dict.removeValueForKey("age")
print(dict)

dict["title"] = "manager"
print(dict)

// 遍历字典(k, v可以随便写)
for (k, v) in dict {
    print("\(k) -- \(v)")
}

// 合并字典
var dict2 = ["name": "wangwu", "age": 80, "title": "boss"]
for (k, v) in dict2 {
    dict.updateValue(v, forKey: k)
}
print(dict)

注意点无论是数组还是字典, 只有相同类型才能赋值

八 字符串

  • oc与Swift对比
    • OC的字符串是NSString, Swift的字符串String
    • OC的字符串是一个对象, Swift字符串是一个结构体, 效率更高
    • OC中的字符串是一个\0结尾, Swift字符串不是以\0结尾
  • 遍历字符串
let str = "我要飞的更High"

for s in str {
    print(s)
}
  • 字符串拼接
let str1 = "zhangsan"
let str2 = "lisi"
str2 += str
str2
  • 格式化字符串
// 可以使用\()在字符串中插入任何数据
let name = "lnj"
let age = 30
let res = "name = \(name), age = \(age)"
res
// 输出:2015-10-09 03:04
let str3 = String(format: "%d-%02d-%02d %02d:%02d", arguments: [2015, 10, 9, 3, 4])
  • 截取字符串
let str4 = "xiaomaguohe"
// as 就是把什么当做什么
(str4 as NSString).substringWithRange(NSMakeRange(4, 2))

九 函数

  • 格式
func 函数名称(形参列表) ->返回值类型
{
    代码
}

func sum(a: Int, b: Int) -> Int {
    return a + b
}
  • 如果没有返回值, -> 返回值 可以省略

    • 默认情况下,在调用函数时,第一个参数名是省略的
  • 1.没有参数没有返回值

func say() -> Void
{
    print("hi")
}
say()
//  简写形式
 func say2()
 {
    print("hi")
 }
 say2()
  • 有参数没有返回值
    • Swift2.0开始, 会自动将形参列表的第二个参数名称作为标签
    • Swift2.0之前是没有这个特性的, 在Swift2.0之前如果需要显示标签需要在形参名称前面加上#
func sum(num1: Int, num2: Int)
{
    print(num1 + num2)
}
sum(10, num2: 20)
  • 没有参数有返回值
func getNumber() -> Int
{
    return 998
}
print(getNumber())
  • 有参数有返回值
func sum2(num1: Int, num2: Int) -> Int
{
    return num1 + num2
}
print(sum2(50, num2: 50))
  • 内部和外部参数
    • 默认情况下所有形参都是内部参数, 也就是说只能在函数内部使用
    • 从Swift2.0开始会自动将形参列表的第二个参数名称作为标签, 也就是说从第二个参数开始, 参数的名称既是内部参数又是外部参数
  • 如何指定外部参数?
func sum3(num1: Int, y num2: Int)
{
    print("num1 = \(num1), num2 = \(num2)")
    print(num1 + num2)
}
//sum3(10, num2: 20)
sum3(10, y: 20)
  • 默认参数

    • 如果指定了默认值, 那么在调用方法的时候就可以不用传递数据, 如果不传递数据系统就会使用默认值, 如果传递了就会使用传递的值
    • 在其它语言里面, 默认值一般情况只能是最后一个参数, 但是Swift可以写在任何位置
  • 常量参数和变量参数以及inout参数

    • 默认情况下所有形参都是常量参数, 不能在函数中修改形参的值
    • 如果想在函数中修改形参的值, 那么必须把形参变为变量参数
    • 和OC一样, 在函数中修改形参的值不会影响到外面实参的值
    • 如果想在函数中修改形参之后影响实参, 那么必须把形参变为inout参数
func swap(inout a: Int, inout b: Int)
{
    print("a = \(a), b = \(b)")
    let temp = a
    a = b
    b = temp
    print("a = \(a), b = \(b)")
}
  • 可变参数
    • 只要参数是可变参数, 就可以传递一个或多个值
    • 在其它语言中一般情况下可变参数只能是最后一个形参, 而Swift中可以写在任意位置, 但是为了提高代码的阅读性, 还是建议写在最后
func sum4(nums: Int..., temp: Int) -> Int
{
    var sum = 0
    for i in nums
    {
        sum += i
    }
    return sum + temp
}
sum4(1, 2, 3, temp: 10)   //  输出结果:16
  • 函数嵌套
    • 将一个函数写到另外一个函数的函数体中, 外面称之为函数嵌套
      • 1.被嵌套的函数只能在父函数内部访问
      • 2.被嵌套的函数可以访问外部的变量
let value = 55
func test()
{
    let number = 10
    func demo()
    {
        print("----\(number), \(value)")
    }
    demo()
}
test()

十 构造函数

  • Swift中要求在创建一个类时必须给这个类中所有的属性进行初始化
    • 如果不能在创建对象时给这个类中所有的属性进行初始化, 那么这些属性必须是可选的
    • 如果已经在构造方法中对所有的属性进行了初始化, 那么这些属性就可以不是可选类型
    • 在给某一个类指定属性的数据类型时, 如果该属性是对象类型, 那么可以指定为可选类型
 // 如果该属性不是对象类型而是基本数据类型, 那么建议直接赋值为0
    var name: String?
    // 如果属性是基本数据类型, 并且是可选类型, 系统不会自动分配存储空间
    var age: Int = 0

    // Person()
    override init() {
        // 注意: 在构造方法中必须先初始化本类再初始化父类
        name = "lnj"
        age = 30
        // 当我们重写一个类的构造方法时, 系统内部会帮我们调用super.init()
        super.init()

    }
  • 自定义构造方法
init(name: String, age: Int)
    {
        self.name = name
        self.age = age
//        以下这一句代码, 能不写就不写
//        super.init()
    }
  init(dict: [String: AnyObject])
    {
      // 注意:Swift中如果想在构造方法中使用KVC转换模型, 必须先调用 super.init()
      // 调用 super.init()的目的主要是为了给对象分配存储空间
        super.init()
        setValuesForKeysWithDictionary(dict)
    }
// Swift中打印对象会调用下面这个属性
    override var description: String {
//   return "name = \(name), age = \(age)"
       let property = ["name", "age"]
       let dict = dictionaryWithValuesForKeys(property)
       return "\(dict)"
    }

注意: Swift开发中一般情况下不用导入头像文件, 因为只要所有的文件都在一个命名空间中那么就可以直接使用
默认情况下一个项目的命名空间就是项目名称, 而在同一个项目下的所有文件都在同一个命名空间中

十一 setter和getter方法

  • setter方法
var name: String?
        {
        // 在Swift开发中用以下两个方法代替OC中的重写setter方法
        willSet{
           print("赋值之前调用 \(newValue)")
        }
        didSet{
            print("赋值之后调用 \(oldValue)")
        }
    }
  • getter方法
    • 只实现 getter 方法的属性被称为计算型属性,等同于 OC 中的 ReadOnly 属性
    • 计算型属性本身不占用内存空间
    • 不可以给计算型属性设置数值
var age: Int
    {
    // 在Swift中如果只重写了get方法, 那么该属性就是一个只读属性readOnly
    // 如果一个属性只重写了get方法, 我们也称之为"计算型属性", 计算型属性是不具备存储能力的
//        get{
//            return 99
//        }
       // 如果只是想重写一个属性的get方法, 那么可以简写
       return 99
    }

十二 闭包

  • OC: block类似于匿名函数, 用于封装代码块, 执行一些耗时操作
  类型: 返回值类型(^block名称)(形参列表)
            值: 
            ^(形参列表){
                需要执行的代码
            }  
  • Swift: 闭包是用于定义函数(Swift中函数就是闭包, 闭包就是一个特殊的函数)
  类型: (形参列表)->返回值类型
            值: 
            {
                (形参列表)->返回值类型
                in
                需要执行的代码
            }
  • 闭包的几种格式
 1. 完整写法
    loadData ({ () -> () in
        print("更新UI")
    })

  2.如果闭包没有形参, 那么inin之前的代码都可以省略
    loadData ({
        print("更新UI")
    })

 3.如果闭包是函数的最后一个参数, 那么闭包可以写在函数()的后面
    loadData (){
        print("更新UI")
    }

 4.如果函数只有一个闭包参数, 那么函数的()可以省略
    loadData {
        print("更新UI")
    }

注意: 在设置闭包属性是可选类型时一定更要用一个()括住闭包的所有的类型, 否则只是指定了闭包的返回值是可选的

// 错误写法: var callback: ()->()?
    var callback: (()->())?
  • 闭包循环引用

    • OC中如何解决: __weak typeof(self) weakSelf = self;
    • Swift中如何解决: weak var weakSelf = self
    • 对应关系: __weak == weak __unsafe_unretained == unowned

    __weak : 如果对象释放, 会自动设置为nil
    __unsafe_unretained: 如果对象释放, 不会自动设置为nil

  • 解决循环引用的方法

  •  weak var weakSelf = self    // 方法1
     loadData { [unowned self] () -> () in    // 方法2
    • deinit 相当于OC中的dealloc方法
       // 只要一个对象释放就会调用deinit方法
        deinit
        {
            print("88")
        }

    十三 懒加载


    • 只有外界访问到listData的时候才会去执行闭包, 然后将闭包的返回值赋值给listData

    注意: 一定要记住闭包后面需要写上(), 代表执行闭包
    lazy var listData: [String]? = {
            ()->[String]
            in
            print("---")
            return ["ls", "zs", "why", "wsz"]
        }()
    
        // 开发中这样写
        lazy var listData2: [String]? = {
            print("---")
            return ["ls", "zs", "why", "wsz"]
            }()

    十四 单例

    • 这是一种写法,不过不常用
     static var onceToken: dispatch_once_t = 0;
        static var _instance: NetworkTools?
    
        class func shareNetworkTools() -> NetworkTools {
            print(onceToken)
            dispatch_once(&NetworkTools.onceToken, {
                _instance = NetworkTools()
            })
            return _instance!
        }
    • 如果在Swift中编写单例, 推荐使用如下写法
      • 苹果有统一的命名规范, 但凡是单例统一是用shareInstance
    static let shareInstance: NetworkTools =  NetworkTools()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值