SwiftSwift基础

Swift 入门学习

2021-07-30  本文已影响0人  阳光下的灰尘

Swift 分享大纲


Swift 简介

Swift 社区有详细的官网介绍和学习入门。
Swift 发布相关历史
Swift 官网快速体验
Swift 官网基础知识
Swift 是苹果于2014年 WWDC(苹果开发者大会)发布的新开发语言,是一个很强大的语言,可以用于 iOS 、iPadOS 、macOS 、tvOS 和 watchOS 等开发。目前最新版本已经到 Swift 5.5,已经趋于稳定,不会出现大量的修改的问题,而且没有了 mac 系统的开发限制,还可以使用 windows,和 Linux 系统进行开发。

Swift 是最新的编程语言研究的结果,结合了几十年构建苹果平台的经验。命名参数用干净的语法表示,这使得 Swift 中的 api 更容易阅读和维护。更好的是,您甚至不需要输入分号。推断类型使代码更整洁,更不容易出错,而模块消除头文件并提供名称空间。为了更好地支持国际语言和表情符号,Strings 是 unicode 正确的,并使用基于 UTF-8 的编码来优化各种用例的性能。使用紧凑的确定性引用计数自动管理内存,在不产生垃圾收集开销的情况下将内存使用保持在最低水平。

Swift 还有许多其他功能,可以让您的代码更富表现力:

Swift 优缺点

Swift 优点
Swift 缺点

Swift 常用的关键词解释和用法

详细的 Swift 关键词解释和用法比较多,就不详细讲解了,就列举几个开发中一定要用的或者最常使用的。
基础的学习可以使用 Swift 的 Playground ,可以不用运行 cmd + r 就可以看到结果,体验不错。

Swift 开发中常用示例

1、基础属性 letvar

let name = "Baron"
var age = 26
var current: String? // 可选型,可以为nil
var currentNormal: String? = "normal"  // 可选型,默认为 "normal"
@objc  var arrayString: [String]?  // 数组,字符串类型 可以在 OC 中使用
private var dicString: [String:String]? // 字典,字符串类型 私有不能跨文件使用

2、函数 func

// funcname 方法名称; name:调用时显示的参数名称; str 函数内使用的参数名称;returntype 返回值
func funcname(name str:String) -> returntype
{
  //  code...
   return parameters
}
// 无参数 无返回值 是类方法
class func funcname() 
{
   Statement1
}

// 无参数 无返回值 是 OC 方法 一般按钮绑定的的方法要使用 @objc
@objc func funcname() 
{
   Statement1
}

3、协议 protocol,与 OC 有不同之处,可以有默认实现。

//oc协议默认可选 swift默认必须实现
@objc protocol VCTypeProtocol where Self: UIViewController  {
    var model: Model { get set }
    func shouldShow(container: VC, completed:@escaping (Bool) -> Void)  // @escaping (Bool) -> Void 是逃逸闭包, 类似 OC 中的异步 block
    func test()
}

extension VCTypeProtocol {
      func test() {
       // 默认实现,继承 VCTypeProtocol 可以不用实现 test 函数就可以直接调用。
      }
}

4、闭包 类似于 OC Block,但是逃逸闭包一般会放在函数的后面实现。

// 无参数 无返回值 
() -> ()
// name:参数 ; String 类型返回值 
(String) -> String

// 逃逸闭包, 类似 OC 中的异步 block,网络回调基本都是逃逸闭包
@escaping (Bool) -> Void)

5、条件判断 if 语句if...else 语句, if...else if...else 语句, switch 语句, guard ... else { ... return }

let name:String? = "lisa"
if  let nameS = name  {
    // nameS 不是Nil 执行
}
else {
     // nameS 是Nil 执行
}
switch expression {
   case expression1  :
      statement(s)
      fallthrough /* 不写这句等于是 break,写了就会执行下面的 case */
   case expression2, expression3  :
      statement(s)  // 默认是 break 的情况  
   default : /* 如果上面的情况已经全部满足可以不用写 defult */
      statement(s);
}
guard let nameS = name else {
     // nameS 是Nil 执行
     return
}
// nameS 不是Nil 执行

6、集合类型
数组(Array): 使用有序列表存储同一类型的多个值, 相同的值可以出现在不同位置中.
集合(Set): 存储相同类型并且没有确定顺序的值, 每个元素只出现一次.
字典(Dictionary): 使用无序的键值对存储相同类型的键和相同类型的值, 每个值(value)都关联唯一的键(key).

字面量创建方式 Array [] , Dictionary [:],Set 有点类似 Array []

// 声明的类型可以不写,Swift 会自动推断, 写声明是为了我们开发者自己可以清楚地知道是什么类型
var dic:Dictionary<String, String> = ["1":"1","2":"2"]
// Dictionary 可以用 int 做 key
var dic2:Dictionary<Int, String> = [1:"1",2:"2"]
var strSet:Set<String> = ["1","2"]
var strArr:Array<String> = ["1","2"]

strArr += ["3","4"]  
// strArr ["1","2","3","4"]
strArr.append("Flour")
// strArr ["1","2","3","4","Flour"]

7、循环遍历,控制流

for item in strArr {
    print("Item:\(item)") 
}
// Item:1
// Item:2
// Item:3
// Item:4
// Item:Flour

for(index,item) in strArr.enumerated() {
    print("index:\(index); Item:\(item)") 
}
// index:0; Item:1
// index:1; Item:2
// index:2; Item:3
// index:3; Item:4
// index:4; Item:Flour

for(key,value) in  dic {
    print("key:\(key); value:\(value)") 
}
// key:1; value:1
// key:1; value:2

// Dictionary 可以用 int 做 key
var dic:Dictionary<Int, String> = [1:"1",2:"2"]
for(key,value) in  dic {
    print("key:\(key); value:\(value)")
}
// key:1; value:1
// key:1; value:2

8、可选型
可选型是在后面添加 ? 来表示的,表示有可能为 nil。在使用是,要进行安全判断,如果确定有值可以进行强制解析,! 表示强制解析,强制解析之后如果是空值,就会崩溃,! 强制解析不安全,尽量的不使用。可以用 ?? 来避免,也可以 if letguard let ... else { return }
?? a ?? b 表示 a 如何不存在即使用 b

var name:String?
// 省略代码 ...
// 后面使用 name,不能确定是否有值,
// 1、可以使用 `??`
let nameS = name ?? "lisa" //  lisa 表示默认值, 也可以默认 "" 空字符串
// 2、if let
if let nameS = name {
// nameS 有值时或是空字符串"" ,才会执行
}
// 3、guard let ... else { return }
guard let nameS = name else {   
    // nameS 为 nil 时,会执行这里面 
    return 
}
// nameS 有值时或是空字符串"",才能执行下面

9、泛型
说到泛型,会想到 Swift 中的 AnyAnyObject 和 OC 中的 id 。那么都有什么区别呢

OC 中的 id

  • id 的定义中,已经包好了*号。id 指针只能指向OC中的对象
  • 为了尽可能的减少编程中出错,Xcode 做了一个检查,当使用 id 类型的调用本项目中所有类中都没有的方法,编译器会报错
  • id 类型不能使用 . 语法,因为 . 语法是编译时特性,而 id 是运行时特性

Swift 中的 AnyAnyObject

概括来说 AnyObject 用于任何类(class)的实例,而 Any 可以用于表示任何变量,包括各种基本类型、值类型以及实例。而在 swift 中,枚举类型和结构体(例如 ArrayDictionary )都属于值类型,因而不能用 AnyObject 来进行修饰。

Swift 中的泛型

通常来讲,泛型为类或者方法提供一个类型参数,以方便某个参数类型保持前后的一致性。

Swift 中的泛型和 Any

//泛型修饰
 func singleGenericFunc<T>(x: T ,y: Int)-> T {
    ......
}

//Any修饰
func singleAnyFunc(x: Any,y:Int) -> Any {
  ......
}

此处最大的不同是,singleGenericFunc 中的参数 x 的类型与方法的返回类型是一致的。而singleAnyFunc 中却没有这个特性。x 与方法的返回类型都可以是任意值,不一定相同。
这是由于泛型的类型检查由编译器负责,而 Any 修饰则避开了类型系统。
综合比较而言,应该尽量多使用泛型,少使用 Any ,以尽量转换类型时发生的类型错误。

10、常见错误处理
常用的有 do-catchtry?、或 try!

Swift 中的错误处理类似于其他语言中的异常处理,使用 try , catchthrow 关键字。与许多语言中的异常处理(包括 Objective-C)不同,Swift 中的错误处理不涉及展开调用堆栈,这是一个计算成本很高的过程。因此,throw 语句的性能特征与语句的性能特征相当 return

要指示函数、方法或初始值设定项可以抛出错误,请 throws 在函数声明中的参数后面写上关键字。标记 throws 为 的函数称为抛出函数。如果函数指定了返回类型,则 throws 在返回箭头 ( ->)之前写上关键字。

func canThrowErrors() throws -> String
func cannotThrowErrors() -> String

您可以使用 do-catch 语句通过运行代码块来处理错误。如果 do 子句中的代码抛出错误,则将其与 catch 子句进行匹配以确定其中哪一个可以处理错误。

do {
    try expression
    statements
} catch pattern 1 {
    statements
} catch pattern 2 where condition {
    statements
} catch pattern 3, pattern 4 where condition {
    statements
} catch {
    statements
}

提倡前往Swift 官网学习

Swift 与 OC 混合开发

1、创建并添加桥接文件 (桥接文件是 Swift 使用 OC 是用的)
如果是 OC 项目与 Swift 混编,创建第一个 Swift 文件,系统会自动生成桥接文件并配置。
如果是 Swift 项目与 OC 混编,创建第一个 OC 文件,系统会自动生成桥接文件并配置。
如果删除了,就需要手动创建 projectName-Bridging-Header.h 的桥接文件,并需要自己手动配置。在 Targets->Bulid Setting ,然后搜索 Swift,选择 Swift Compiler-General 下 Objective-C Bridging Header ,然后配置文件路径。
2、使用方法
Swift 文件使用 OC, 只需要把 OC 的 .h 文件导入在 projectName-Bridging-Header.h 文件中即可

Swift 文件使用 OC 文件

OC 文件使用 Swift ,需要在 OC 文件中导入头文件 projectName-Swift.h
projectName-Swift.h(这个是 xcode 自动生成的,并配置好的路径,是找不到文件,但是真是生成的,是把 Swift 编译成 OC 的形式)

OC 文件使用 Swift 文件

3、OC宏文件
Swift 中是不能使用宏定义语法,但是因为命名空间的缘故,在其中,我们将原本 OC 中不需要接受参数的宏,定义成 let 常量或枚举,将需要接受参数的宏定义成函数。

let UScreenWidth = UIScreen.main.bounds.width
let UScreenHeight = UIScreen.main.bounds.height

var topVC: UIViewController? {
    var resultVC: UIViewController?
    resultVC = _topVC(UIApplication.shared.keyWindow?.rootViewController)
    while resultVC?.presentedViewController != nil {
        resultVC = _topVC(resultVC?.presentedViewController)
    }
    return resultVC
}

var isIphoneX: Bool {
    return UI_USER_INTERFACE_IDIOM() == .phone
        && (max(UIScreen.main.bounds.height, UIScreen.main.bounds.width) == 812
        || max(UIScreen.main.bounds.height, UIScreen.main.bounds.width) == 896)
}

private  func _topVC(_ vc: UIViewController?) -> UIViewController? {
    if vc is UINavigationController {
        return _topVC((vc as? UINavigationController)?.topViewController)
    } else if vc is UITabBarController {
        return _topVC((vc as? UITabBarController)?.selectedViewController)
    } else {
        return vc
    }
}

5、开发时提示情况
Swift 文件中使用 OC 的方法或属性时,有可能没有提示,需要敲代码出来,如果敲的正确,可以正常编译和运行。

SwiftUI

SwiftUI官网
SwiftUI简单认识,SwiftUI 是一种使用Swift语言在苹果设备上构建用户界面的创新且简单的方式。使用 SwiftUI 在苹果设备上创建用户界面可以使用一套统一的工具和 API。SwiftUI 使用声明式的 Swift 语法,代码易读并且写起来很自然。同时它可以和 Xcode 中的设计工具配合使用,让设计工具中的展示样式和代码同步起来。使用 SwiftUI 创建的用户界面自动支持了动态类型(Dynamic Type)、暗黑模式(Dark Mode)、语言本地化(Localization)以及所有人都可以使用的可访问性(Accessibility),也就是说,创建用户界面时,SwiftUI 写的代码比使用其它方式写的代码具有更多的功能。

SwiftUI简单界面搭建

这种声明式语法与最近很火的快平台开发语言 Flutter 一样。SwiftUI 就不细讲了,总体来说比较简单,重点在于大量的实践,只有大量实践才能对 API 快速掌握和熟练应用。
那么为什么会提到 SwiftUI 呢,那就要先了解一下 iOS 提出的小组件功能了。

ios 常用小组件开发

1、Today Widget 小组件
Today Widget 小组件
2、WidgetExtension 小组件
WidgetExtension 小组件

自iOS8之后,苹果支持了扩展(Extension)的开发,开发者可以通过系统提供给我们的扩展接入点 (Extension point) 来为系统特定的服务提供某些附加的功能。
但iOS14后,苹果更新了扩展组件,引入了新的UI组件:WidgetKit 而舍弃了iOS14以下版本的 Today Extension 组件

WidgetExtension 使用的是新的 WidgetKit 不同于 Today Widget,它只能使用 SwiftUI 进行开发,所以需要 SwiftUI 和 Swift 基础
Widget 只支持3种尺寸systemSmall(2x2)、systemMedium(4x2)、systemLarge(4x4)
默认点击 Widget 打开主应用程序
Widget 类似于 Today Widget 是一个独立运行的程序,需要在项目中进行 App Groups 的设置才能使其与主程序互通数据,这点与 Today Widget 相同
Apple官方已经弃用 Today Extension,Xcode12 已经不再提供 Today Extension 的添加,已经有 Today Widget 的应用则会显示到一个特定的区域进行展示

所以如果需要开发 WidgetExtension 小组件就需要了解 SwiftUI 了。

提供学习的 Swift 项目

仿有妖气漫画项目:https://github.com/spicyShrimp/U17

提供学习的 SwiftUI 项目

SwiftUI 官网教程:https://swiftui.jokerhub.cn/tutorials
Copy官网学习项目:https://gitee.com/sihj/swift-ui_study

参考博客

Swift 社区
Swift 官网快速体验
Swift 官网基础知识
Swift 介绍及优缺点
Swift 中的权限控制
Swift 关键词解释和用法
Swift对比Objective-C的优缺点

上一篇 下一篇

猜你喜欢

热点阅读