分类 swift 下的文章

[TOC]

什么是swiftUI?

Apple的解释:

更好的应用。更少的代码。

SwiftUI是一种创新的,非常简单的方法,可以通过Swift的强大功能在所有Apple平台上构建用户界面。仅使用一组工具和API为任何Apple设备构建用户界面。SwiftUI具有易于阅读和自然编写的声明式Swift语法,可与新的Xcode设计工具无缝协作,使您的代码和设计完美同步。自动支持动态类型,暗模式,本地化和可访问性意味着您的第一行SwiftUI代码已经是您编写过的最强大的UI代码。

声明性语法

SwiftUI使用声明性语法,因此您可以简单地说明您的用户界面应该做什么。例如,您可以编写需要包含文本字段的项目列表,然后描述每个字段的对齐方式,字体和颜色。您的代码比以前更简单,更易于阅读,从而节省您的时间和维护。

import SwiftUI
struct Content : View {
  @State var model = Themes.ListModel
  var body: some View {
    List(model.items,action: model.selectItem){ item in
      Image(item.image)
      VStack(alignment: .leading){
        Text(item.title)
        Text(item.subtitle)
            .color(.gray)
      }
    }
  }
}

这种声明式风格甚至适用于复杂的概念,如动画。轻松地将动画添加到几乎任何控件中,并选择只有几行代码的即用型效果集合。在运行时,系统会处理创建平滑移动所需的所有步骤,甚至可以处理中断以保持应用稳定。通过动画这么简单,您将寻找新的方法来让您的应用程序活跃起来。

设计工具

Xcode 11包含直观的新设计工具,使得使用SwiftUI构建界面就像拖放一样简单。当您在设计画布中工作时,您编辑的所有内容都与相邻编辑器中的代码完全同步。在您键入时,代码会立即显示为预览,您对该预览所做的任何更改都会立即显示在您的代码中。Xcode会立即重新编译您的更改,并将其插入到应用程序的运行版本中,始终可见且可编辑。
拖放。只需拖动画布上的控件即可在用户界面中排列组件。单击以打开检查器以选择字体,颜色,对齐方式和其他设计选项,并使用光标轻松重新排列控件。许多这些可视化编辑器也可以在代码编辑器中使用,因此您可以使用检查器为每个控件发现新的修改器,即使您更喜欢手动编码界面部分。您还可以从库中拖动控件并将其拖放到设计画布上或直接放在代码上。
动态更换。Swift编译器和运行时完全嵌入到Xcode中,因此您的应用程序将不断构建和运行。您看到的设计画布不仅仅是您的用户界面的近似 - 它是您的实时应用程序。Xcode可以直接在您的实时应用程序中使用“动态替换”交换已编辑的代码,这是Swift中的一项新功能。
预览。您现在可以创建任何SwiftUI视图的一个或多个预览以获取示例数据,并配置用户可能看到的几乎任何内容,例如大字体,本地化或暗模式。预览还可以在任何设备和任何方向上显示您的UI。

所有Apple平台都是原生的

SwiftUI建立在数十年创建世界上最具创新性和直观的用户界面的经验之上。用户喜欢Apple生态系统的所有内容,例如控件和特定于平台的体验,都会在您的代码中呈现出来。SwiftUI是真正的原生,因此您的应用程序可以通过少量代码和交互式设计画布直接访问每个平台的成熟技术。

对开发者和公司的影响

通过swiftUI的发布可以看到,Apple 在逐步拜托对 Objective-C & Cocoa 的依赖,将精力和资源倾斜到swift语言上,这一次是对UIKit的摆脱。以 Apple 一贯的强势政策,很有可能后期会逐步放弃对 Objective-C 的持续优化(事实上有证据表明已经开始了)和App Store 上的政策制裁。以到达逐步引导开发者加入到新的平台上,这是在之前有过先例的:比如Mac OS从 power-pc 架构转到 x86架构.这将会是一个逐步渐进的过程,但是不会太长最多一两年,并且改变不可逆。
对于公司和开发者来说,最好的莫过于全面拥抱 swift,但是考虑到很多旧项目使用 OC ,已经形成了强大的路径依赖,越大的项目组转身会越困难。但是大项目组人力不缺,资源不缺,有强大的容错能力,我认为反而是大项目组会最早探索,转身稳中有快。而对于新项目和创业公司来说则没有任何技术债务,技术选型会更轻松一些,完全受开发人员的控制。而最尴尬的莫过于中型项目和团队。人手紧缺,业务变动剧烈,最关键的是技术leader如果没有技术前瞻性的话,担心在技术转型中影响业务发展,反而是最保守的。处在这个位置的开发人员是最痛苦的。
解决办法就是:开发自己的项目,拥有完全独立自主的决定权。代价就是每年$99≈¥688。
公司的解决方案就是:在新的项目中使用swift。不建议使用混合开发,编译速度慢,有想想不到的问题

版本要求

SwiftUI 支持的设备要求版本较高,将在7月份开启公测,官方介绍如下:
只支持
Xcode 11+ Bata
iOS 13.0+ Beta
macOS 10.15+ Beta
UIKit for Mac 13.0+ Beta
tvOS 13.0+ Beta
watchOS 6.0+ Beta



title: as as! as?
date: 2016-10-26 13:52:46
tags: as
categories: Swift

id: 2

Swift开发之 is、 as、as!、as?三种类型转换操作符
1,as使用场合
(1)从派生类转换为基类,向上转型(upcasts)
class Animal {}
class Cat: Animal {}
let cat = Cat()
let animal = cat as Animal
(2)消除二义性,数值类型转换
let num1 = 42 as CGFloat
let num2 = 42 as Int
let num3 = 42.5 as Int
let num4 = (42 / 2) as Double
(3)switch 语句中进行模式匹配
如果不知道一个对象是什么类型,你可以通过switch语法检测它的类型,并且尝试在不同的情况下使用对应的类型进行相应的处理。
switch animal {
case let cat as Cat:
    print("如果是Cat类型对象,则做相应处理")
case let dog as Dog:
    print("如果是Dog类型对象,则做相应处理")
default: break
}
2,as!使用场合
向下转型(Downcasting)时使用。由于是强制类型转换,如果转换失败会报 runtime 运行错误。
class Animal {}
class Cat: Animal {}
let animal :Animal  = Cat()
let cat = animal as! Cat
3,as?使用场合
as? 和 as! 操作符的转换规则完全一样。但 as? 如果转换不成功的时候便会返回一个 nil 对象。成功的话返回可选类型值(optional),需要我们拆包使用。
由于 as? 在转换失败的时候也不会出现错误,所以对于如果能确保100%会成功的转换则可使用 as!,否则使用 as?
let animal:Animal = Cat()
if let cat = animal as? Cat{
    print("cat is not nil")
} else {
    print("cat is nil")
}
4,is使用场合
用类型检查操作符(is)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false

weak和unowned都是解决循环引用的关键字
区别:
如果您是一直写 Objective-C 过来的,那么从表面的行为上来说 unowned 更像以前的 unsafe_unretained,而 weak 就是以前的 weak。
用通俗的话说,就是 unowned 设置以后即使它原来引用的内容已经被释放了,它仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil。如果你尝试调用这个引用的方法或者访问成员属性的话,程序就会崩溃。
而 weak 则友好一些,在引用的内容被释放后,标记为 weak 的成员将会自动地变成 nil (因此被标记为 @weak 的变量一定需要是 Optional 值)。
关于两者使用的选择,Apple 给我们的建议是如果能够确定在访问时不会已被释放的话,尽量使用 unowned,如果存在被释放的可能,那就选择用 weak。

@noescape:no escape(没有逃脱)
用来修饰闭包,含义为非逃逸闭包。
当闭包作为参数传递进函数时,如果这个闭包只在函数中被使用,则开发者可以将这个闭包声明成非逃逸的,即告诉系统当此函数结束后,这个闭包的生命周期也将结束,这样做的好处是可以提高代码性能,将闭包声明成非逃逸的类型使用@noescape关键字。
(1) 默认,swift 3.0 弃用,函数结束后,这个闭包的生命周期也将结束。
(2) 在其内部如果需要使用self这个关键字,self可以被省略。
@escaping 逃逸闭包
逃逸的闭包常用于异步的操作,这类函数会在异步操作开始之后立刻返回,但是闭包直到异步操作结束后才会被调用。例如这个闭包是异步处理一个网络请求,只有当请求结束后,闭包的生命周期才结束。当闭包作为函数的参数传入时,很有可能这个闭包在函数返回之后才会被执行。
@autoclosure 自动闭包
(1)默认非逃逸
(2)闭包也可以被自动的生成,这种闭包被称为自动闭包,自动闭包自动将表达式封装成闭包。
(3)自动闭包不接收任何参数,被调用时会返回被包装在其中的表达式的值。
(4)当闭包作为函数参数时,可以将参数标记 @autoclosure 来接收自动闭包。
(5)自动闭包能够延迟求值,因为代码段不会被执行直到你调用这个闭包。
(6)自动闭包默认是非逃逸的,如果要使用逃逸的闭包,需要手动声明: @autoclosure @escaping 旧版本:@autoclosure(escaping)
//(a)自动闭包演示
var students = ["A","B","C"]
let studentsProvider = { students.remove(at: 0) } //自动闭包自动将表达式封装成闭包
studentsProvider()//(b)自动闭包演示
var list = [1,2,3,4,5,6]
//创建一个显式闭包
let closures = {
list.append(7)
}
print(list)//将打印[1,2,3,4,5,6]
closures()
print(list)//引用传递,将打印[1,2,3,4,5,6,7]
func func1(closure: ()->Void) -> Void {
//执行显式的闭包
closures()
}
func func2(auto: @autoclosure ()->Void) -> Void {
//执行自动闭包
auto()
}
//显式闭包
func1(closure: closures)
print(list) //将打印[1,2,3,4,5,6,7,7]
//将表达式自动生成闭包
func2(auto: list.append(8))
print(list)//将打印[1,2,3,4,5,6,7,7,8]