Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Swift基础语法(四)

Swift基础语法(四)

作者头像
拉维
发布于 2020-07-06 02:22:13
发布于 2020-07-06 02:22:13
4.1K00
代码可运行
举报
文章被收录于专栏:iOS小生活iOS小生活
运行总次数:0
代码可运行

Result

在Swift5之前,我们一般是采用上面的方式来处理异常,在Swift5之后,苹果推出了一个Result枚举,Result枚举可以更加优雅地去处理异常。

比如说,在iOS开发中有这样一个网络请求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let request = URLRequest(url: URL(string: "https://xxx")!)

URLSession.shared.dataTask(with: request) { (data, response, error) in
    if error != nil {
        //处理错误error
    } else {
        //处理数据data
    }
}

这里有三个参数:(Data?, URLResponse?, Error?) ,他们都是可选型。当请求成功时,data参数包含response中的数据,error是nil;当发生错误时,error指明具体的错误,data为nil。显然,data和error是互斥的,不存在data和error同时为nil,或者同时非nil的情况,但是编译器是无法确认此事实的。所以在Swift5中,新增了一个枚举Result,使我们能够更简单、更清晰地处理复杂代码中的错误。

定义

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public enum Result<Success, Failure> where Failure : Error {
    //A success, storing a 'Success' value
    case success(Success)

    //A failure, storing a 'Failure' value
    case failure(Failure)
}

这里的Result枚举接受了两个泛型参数,一个是Success,一个是Failure,但是Failure必须遵循Error协议。

这里的Success代表正确执行的值,Failure代表出现问题时的错误值。

一个简单的案例

前面我们举过这样一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

// 定义异常
enum FileReadError : Error {
    case FileIsNull // 路径为空
    case FileNotFound // 路径下对应的文件不存在
}

// 改进方法,让方法抛出异常
func readFileContent(filePath : String) throws -> String {
    //1,路径为空字符串
    if filePath == "" {
        throw FileReadError.FileIsNull
    }

    //2,路径有值,但是该路径下没有对应的文件
    if filePath != "/user/desktop/123.plist" {
        throw FileReadError.FileNotFound
    }

    //3,正确获取到文件内容
    return "123"
}

现在我们将上例改为使用Result来处理异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 定义异常
enum FileReadError : Error {
    case FileIsNull // 路径为空
    case FileNotFound // 路径下对应的文件不存在
}

// 改进方法,让方法抛出异常
func readFileContent(filePath : String) -> Result<String, FileReadError> {
    //1,路径为空字符串
    if filePath == "" {
        return .failure(.FileIsNull)
    }

    //2,路径有值,但是该路径下没有对应的文件
    if filePath != "/user/desktop/123.plist" {
        return .failure(.FileNotFound)
    }

    //3,正确获取到文件内容
    return .success("123")
}

let result = readFileContent(filePath: "/user/desktop/123.plist")

// 处理result
switch result {
case .failure(let error):
    switch error {
    case .FileIsNull:
        print("路径为空")
    case .FileNotFound:
        print("路径下对应的文件不存在")
    }
case .success(let content):
    print(content)
}

异步失败处理案例

使用闭包来处理Result:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 定义 Error
enum NetworkError : Error {
    case UrlInvalid
}

// 定义一个函数,包含一个逃逸闭包进行异步回调
func getInfo (from urlString : String, completionHandler : @escaping (Result<String, NetworkError>) -> Void){
    if urlString.hasPrefix("https://") {
        //经过一系列网络处理以后得到一个服务器返回的数据
        let data = "response result"
        //获取数据
        completionHandler(.success(data))
    } else {
        //URL有问题
        completionHandler(.failure(.UrlInvalid))
    }
}

//调用函数
getInfo(from: "777") { (result) in
    //处理Result
    switch result {
    case .failure(let error):
        switch error {
        case .UrlInvalid:
            print("Url有问题")
        }
    case .success(let content):
        print(content)
    }
}

元类型、.self和Self

元类型、.self

获取一个对象的类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var str = "Hello, playground"
type(of: str) // String.Type

元类型,可以理解成是类型的类型,通过类型.Type来定义,既然是类型,就可以修饰变量或者常量,如何得到这种类型呢?需要通过类型.self

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var str = "Hello, playground"
type(of: str) // String.Type
type(of: str.self) // String.Type

var a = String.self
type(of: a) // String.Type.Type

协议的元类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protocol TestProtocol {

}

TestProtocol.self // TestProtocol.Protocol

Self与协议

在定义协议的时候,Self使用的频率很高,用于协议(protocol)中限制相关的类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//限定遵循该协议的代理者必须是UIView或者其子类类型
protocol TestProtocol {
    func eat() -> Self
}

extension TestProtocol where Self : UIView{

}

@objc关键字

Swift中,很多地方都用到了@objc关键字,尤其是在一些混编项目中。出于安全的考虑,我们需要在暴露给OC使用的类、属性和方法前面加上@objc。那么在Swift中,哪些地方用到了这个关键字呢?

1,#selector中调用的方法需要在方法声明前面加上@objc

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .contactAdd)
        button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
    }

    @objc func buttonClicked() {
        print("buttonClicked")
    }
}

2,协议的方法可选时,协议和可选方法前要用@objc声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@objc protocol OptionalProtocol {
    @objc optional func protocolMethod1()
    @objc optional func protocolMethod2()
}

3,用weak修饰delegate属性时,协议前要用@objc声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@objc protocol ViewControllerDelegate {
    func protocolMethod1()
    func protocolMethod2()
}

class ViewController: UIViewController {
    weak var delegate : ViewControllerDelegate?
}

4,类的前面加上@objcMembers,则该类以及它的子类、延展里面的方法都会隐式地加上@objc

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@objcMembers
class NormanClass {
    func work(){}
}

extension NormanClass {
    func eat() {}
    func sleep() {}
}

如果此时扩展里面不想加@objc,那么可以使用@nonobjc关键字来修饰

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@objcMembers
class NormanClass {
    func work(){}
}

@nonobjc extension NormanClass {
    func eat() {}
    func sleep() {}
}

5,扩展前面加上@objc,那么该扩展里面的方法都会隐式加上@objc

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NormanClass {
    func work(){}
}

@objc extension NormanClass {
    func eat() {} // 包含隐式的@objc
    func sleep() {} // 包含隐式的@objc 
}

where关键字

在Swift中,很多地方都用到了where关键字,这里的where和数据库中的where差不多,都是用于条件过滤。where关键字在Swift中非常强大,那么在Swift中哪些地方用到了这个关键字呢?

1,switch-case中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        let names = ["张三", "李四", "王五", "李六"]
        for name in names {
            switch name {
            case let x where x.hasPrefix("李"):
                print("姓王的有\(x)")
            default:
                print("你好啊,\(name)")
            }
        }

2,for循环中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        let array = [1,2,3,4,5,6,7,8,9]
        for num in array where num%2==0 {
            print(num)
        }

3,protocol协议中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protocol SomeProtocol {
    
}

extension SomeProtocol where Self : UIView {
    //只给遵守SomeProtocol协议的UIView添加了扩展
    func getInfo() -> String {
        return "属于UIView类型"
    }
}

extension UIButton : SomeProtocol {
    
}

let button = UIButton()
button.getInfo() // 属于UIView类型

4,泛型中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
protocol SomeProtocol {
    func play()
}

class Student : SomeProtocol {
    func play() {
        print("student play")
    }
}

//泛型必须遵守SomeProtocol协议
func test<T>(company : T) where T : SomeProtocol {
    company.play()
}

test(company: Student())

5,do-catch异常处理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum ExcentionError : Error {
    case httpCode(Int)
}

func throwError() throws {
    throw ExcentionError.httpCode(404)
}

do {
    try throwError()
} catch ExcentionError.httpCode(let codeNum) where codeNum == 404 {
    print("not found error")
}

Key Path

我们可以通过KeyPath来间接设置/获取值

Swift中没有原生的KVC概念,但是可以利用KeyPath来间接地实现KVC。

如果要使用KeyPath,则类必须继承自NSObject,否则不能用。

哪些属性可以通过KeyPath进行操作,就需要在其前面加上@objc

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Student : NSObject {
    @objc var name : String
    @objc var age : Int
    var birthday : String
    var gender : String
    
    init(name : String, age : Int, birthday : String, gender : String) {
        self.name = name
        self.age = age
        self.birthday = birthday
        self.gender = gender
    }
}

var student = Student(name: "norman", age: 18, birthday: "19910910", gender: "male")

//获取值
student.name
//Swift 3 之前
student.value(forKey: "name")
//Swift 3
student.value(forKeyPath: #keyPath(Student.name))
//Swift 4
student[keyPath:\Student.name]

//设置值
student.age = 20
//Swift 3 之前
student.setValue(22, forKey: "age")
//Swift 3
student.setValue(24, forKeyPath: #keyPath(Student.age))
//Swift 4
student[keyPath:\Student.age] = 26

Codable协议

我们在开发中经常会碰到结构体或者类与JSON数据的相互转换,尤其是网络请求数据的时候将服务器返回的JSON转成Model。

我们在使用OC的时候可以使用KVC、NSJSONSerialization实现JSON转Model;在Swift4之后,我们使用Codable协议,通过编解码操作实现JSON与Model之间的互相转换。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// JSON
let response = """
{
"name":"norman",
"birthday":"19900803",
"gender":"male",
"age":18
}
"""

// 定义结构体实现codable,一般情况下属性名要与JSON的key一致,否则需要额外处理
struct Student : Codable {
    let name : String
    let birthday : String
    let gender : String
    let age : Int
}

// JSON 转为结构体、类,解码,decode
let decoder = JSONDecoder()

do {
    let student : Student = try decoder.decode(Student.self, from: response.data(using: .utf8)!)
    print(student.name, student.birthday, student.gender, student.age) // norman 19900803 male 18
} catch {
    print(error)
}

// 编码,encode,结构体、类转成JSON
let student = Student(name: "lavie", birthday: "19910910", gender: "male", age: 29)

let encoder = JSONEncoder()

if let jsonData = try? encoder.encode(student) {
    print(String(data: jsonData, encoding: .utf8)!) // {"gender":"male","age":29,"name":"lavie","birthday":"19910910"}
}

字段不匹配处理

注意,上面的例子中,结构体中的属性名称与JSON中的字段名一致。当不一致的时候,需要做特殊处理,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// JSON
let response = """
{
"name":"norman",
"birthday":"19900803",
"gender":"male",
"age":18
}
"""

// 定义结构体实现codable,一般情况下属性名要与JSON的key一致,否则需要额外处理
struct Student : Codable {
    let name : String
    let birthDay : String //⚠️这个名称与JSON中的名称不一致,所以需要做特殊处理
    let gender : String
    let age : Int
    
    //注意,要写全所有的属性
    enum CodingKeys : String, CodingKey {
        case name
        case birthDay = "birthday" // 匹配JSON中的字段和结构体中的字段
        case gender
        case age
    }
}

// JSON 转为结构体、类,解码,decode
let decoder = JSONDecoder()

do {
    let student : Student = try decoder.decode(Student.self, from: response.data(using: .utf8)!)
    print(student.name, student.birthDay, student.gender, student.age) // norman 19900803 male 18
} catch {
    print(error)
}

// 编码,encode,结构体、类转成JSON
let student = Student(name: "lavie", birthDay: "19910910", gender: "male", age: 29)

let encoder = JSONEncoder()

if let jsonData = try? encoder.encode(student) {
    print(String(data: jsonData, encoding: .utf8)!) // {"gender":"male","age":29,"name":"lavie","birthday":"19910910"}
}

需要注意的是,当使用CodingKey解决字段不一致的情况的时候,哪怕只有一个字段不一致,也需要在里面将所有字段列出。

访问权限

模块和源文件

模块:独立的单元构建和发布单位,可以理解为一个特定功能的代码集合,并且可以使用Swift的import关键字导入到另一个模块。

需要注意的是,模块不是目录,也不是文件夹,而是某个功能的集合。比如UIKit框架、Foundation框架,还有第三方框架等,都是一个模块。

源文件:单个Swift源代码文件。注意,模块是包含源代码的。

访问权限

访问权限从大到小依次为:

  1. open:允许实体被定义模块中的任意源文件访问,也可以被另一模块的源文件通过导入该定义模块来访问。也就是说,可以在任何地方访问,包括override和继承
  2. public:跟open一样,可以在任何地方访问。但是与open不同的一点是,public在其他模块中不可以被override和继承,而在本模块内部可以被override和继承。
  3. internal(默认):允许实体被定义模块中的任意源文件访问,但是不能被该模块之外的任意源文件访问。新建文件时默认为Internal。
  4. fileprivate:将实体的使用范围限制在当前源文件内。
  5. private:只在当前类中能被访问。需要注意的是,Swift4之后,private属性的作用域扩大到了extention中,也就是说,在扩展中也能访问private属性。

playground可视化开发

我们可以在playground中进行界面开发:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import UIKit
import PlaygroundSupport // 需要导入PlaygroundSupport模块

//UIViewController
class NormanViewController : UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .orange
    }
}

extension NormanViewController {
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = String(indexPath.row)
        return cell
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("did select \(indexPath.row)")
    }
}

let vc = NormanViewController()
//将显示的内容赋值给PlaygroundPage.current.liveView
PlaygroundPage.current.liveView = vc

混合开发

在iOS开发中,难免会遇到Swift和Objective-C这两种语言同时存在的情况,如果在同一个项目中,两种语言并存,那么该项目就是一个混合项目。在混合项目中,就会存在两种语言相互调用的情况。那么,如何才能在一个项目中让两种语言可以相互调用呢?Apple给我们做好了桥接工作,不过,在OC项目中调用Swift,与在Swift项目中调用OC,处理的方式是不一样的。

Swift项目中调用Objective-C

1,新建一个Swift的iOS项目

2,创建一个OC的类,此时会有如下提示,选择Create Bridging Header:

这个提示的大意是:添加这个文件会创建一个Swift和OC的混合项目,你是否希望Xcode自动配置一个桥接头文件来让两种语言的类文件相互可见?

3,此时项目中会多出三个文件,分别是创建的两个OC文件和一个BridgingHeader文件

4,修改OC类文件如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface NormanButton : UIButton
- (void)test;
@end

@implementation NormanButton
- (void)test {
    NSLog(@"test");
}
@end

5,在Bridging Header文件中导入所有的需要使用的Objective-C类的头文件,如下所示:

6,直接在Swift文件中使用OC文件中定义的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = NormanButton()
        button.test() // test
        
    }

}

OC 项目中调用Swift

1,新建一个Objective-C项目

2,创建一个Swift的类,继承自NSObject,此时也会有上面的提示,选择Create Bridging Header

3,此时项目中会多出两个文件,分别是创建的Swift文件和Bridging Header文件。BridgingHeader文件里虽然什么都没有,但是其内部已经为我们做了很多事情。

4,Swift文件内容如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import UIKit

class NormanPerson: NSObject {
    //在Swift代码中,将需要暴露给OC调用的属性和方法前面加上@objc关键字
    @objc func eat() {
        print("吃饭了~")
    }
}

5,在OC类中导入头文件,注意此时导入的头文件是一个命名为 项目名-Swift.h 的头文件,而不是BridgingHeader文件。

6,在OC代码中调用Swift:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import "ViewController.h"
//导入"项目名-Swift.h文件"
#import "NormanOC-Swift.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Person *person = [[Person alloc] init];
    [person eat];
}

@end

关于Bridging Header文件

如果BridgingHeader文件不是Xcode帮助新建的,而是我们自己手动创建的头文件,那么会因为找不到“桥接文件”而编译失败,此时需要在Building setting里面搜索bridging关键字,将文件的路径值改成桥接文件的实际路径即可。

命名空间

命名空间(nameSpace)在C++、C#中是一个常见的概念,OC中是没有命名空间的概念的,但是在Swift中引入了命名空间的机制。

为什么需要命名空间

简而言之就是一句话:为了避免命名上的冲突

在开发中,尤其是在多模块开发中,很难保证模块之间的类名不会重复。为了保证不同模块下同名的类可以正常使用而不报错,此时就需要命名空间了。命名空间可以保证即使创建的类名一样,但只要命名空间不一样,这些同名的类也是不一样的。所以,命名空间是一种安全机制,我们可以用它来防止冲突。

Swift中的类名的完整形式是:“命名空间+类名”,我们可以尝试在类中打印当前类来查看一下完整名字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        print(self) // <NormanSwift.ViewController: 0x7fd976c0c070>
    }

}

命名空间的查看与修改

从上例的打印结果来看,命名空间是我们项目的名字,那么如何查看命名空间的名字呢?

首先,使用源代码的形式打开项目中的info.plist文件;

然后找到CFBundleExecutable,它对应的值就是命名空间。

如果要修改命名空间,注意不要直接编辑info.plist,可以进入Build Settings中搜索product name进行修改。

在程序中获取命名空间

通过上面的介绍我们已经知道可以通过info.plist来获取命名空间的名称,那么如何代码解析info.plist,并拿到CFBundleExecutable所对应的值呢?如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"]
  //返回的是一个可选型
  print(nameSpace) // Optional(LavieSwift)

命名空间在开发中的使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //通过类名来新建一个类
    func vcWithName(vcName : String) -> UIViewController? {
        //获取命名空间
        guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else {
            print("获取失败")
            return nil
        }
        
        //拼接完整的类
        guard let vcClass = NSClassFromString(nameSpace + "." + vcName) else {
            print("获取类名失败")
            return nil
        }
        
        //转换成UIViewController
        guard let vcType = vcClass as? UIViewController.Type else {
            print("转换失败")
            return nil
        }
        
        //根据类型创建对应的控制器
        let vc = vcType.init()
        return vc
    }

总结

到这里,我们花了四篇文章的篇幅将常用的Swift基础语法介绍了一遍。接下来我们将开启Swift进阶阶段的学习,加油~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Swift基础语法(三)
chineseScore和mathScore也是存储属性,用来记录该学生的语文分数和数学分数。
拉维
2020/06/23
2.1K0
Swift基础语法(三)
Swift| 基础语法(四)
总结下 swift下的基础语法,里面涉及到:常量&变量、Swift中的数据类型、逻辑分支、循环、字符串相关、数组和字典、方法的书写调用等内容,考虑到阅读体验分多篇来展示,希望对大家学习swift有所帮助,同时也是对自己的一个总结。
進无尽
2018/09/12
1.4K0
Swift| 基础语法(四)
Swift 5.6 新特性
Swift 5.6 之前只有#available表示可用,Swift 5.6 之后增加了#unavailable表示不可用,二者意思相反。
YungFan
2022/03/30
1.3K0
Swift基础语法简化版(续)
闭包能够捕获和存储定义在其上下文中的任何常量和变量,即闭合并包裹那些常量和变量,因此被称为“闭包”。
拉维
2020/06/23
1.6K0
swift4.0语法杂记(精简版)
一、swift简史 1、介绍 swift是苹果公司于2014年推出用于撰写OS和iOS应用程序的语言。它由苹果开发者工具部门总监“克里斯.拉特纳”在2010年开始着手设计,历时一年完成基本的架构。到后来苹果公司大力投入swift语言的研发,于2014年发布这一语言的第一版本。swift2.0之后的语法则趋于稳定,2017年发布的swift4.0虽有改动,但也只是增添了一些新特性。这些新特性需要在Xcode9上运行才能显示出效果。值得一提的是它支持unicode9,也就是说,可以用某些图片图标来充当变量。
谦谦君子修罗刀
2018/05/02
15.6K0
swift4.0语法杂记(精简版)
Swift基础语法简化版
该网站是对Swift官方文档的翻译,但不是无脑翻译,而是结合作者的开发经验,在翻译的基础上,给出一些实用的建议。
拉维
2020/06/23
3.9K0
Swift基础语法(一)
Swift语言是苹果公司在Apple WWDC 2014上退出的,用来撰写MacOS和iOS应用程序。
拉维
2020/05/22
4.4K0
Swift 5.8 新特性
Swift 5.3 之后 self 可以在闭包中有条件省略,Swift 5.8 之后类中的[weak self]也可以省略 self。
YungFan
2023/03/30
1.5K0
Swift 6.0 新特性
Swift 发布十周年之际 Apple 推出了大版本 Swift 6.0,其内置于 Xcode 16,带来了如下的新特性。
YungFan
2024/07/05
2770
Swift学习之5.3新特性
Swift 5.3 之前即使有多个尾随闭包也只有最后一个能被写成精简的形式,这种写法一个闭包在圆括号内,另一个在外面。新的写法把这些闭包都放在圆括号外面,显得更加简洁。注意:尾随闭包中的第一个闭包的标签会被强制省略。
YungFan
2021/01/05
5980
36.Swift学习之Associated Object
Swift 可以利用 OC 的 runtime 和 KVC ,在运行时向一个对象添加值存储,这种方式称之为Associated Object。在使用 extension 扩展现有类的功能时,使用Associated Object的方式,可以将一个值 “关联” 到已有的要扩展的类上。该知识点在 iOS 开发中使用往往能优雅地解决很多问题。
YungFan
2019/09/29
2.2K1
Swift| 基础语法(五)
总结下 swift下的基础语法,里面涉及到:常量&变量、Swift中的数据类型、逻辑分支、循环、字符串相关、数组和字典、方法的书写调用等内容,考虑到阅读体验分多篇来展示,希望对大家学习swift有所帮助,同时也是对自己的一个总结。
進无尽
2018/09/12
2.3K0
Swift| 基础语法(五)
Swift 3到5.1新特性整理
Swift 5.0 最重要的自然是ABI Stability, 对此可以看这篇 Swift ABI 稳定对我们到底意味着什么 。
小刀c
2022/08/16
4.8K0
Swift 3到5.1新特性整理
Swift Runtime ?
你肯定也想过       在OC中相信每一个iOS开发都知道Runtime, 现在Swift也更新到4.0版本了,要是你也学习过Swift的话你可能也会想过这样一个问题,OC大家都知道是有动态性的,你能通过Runtime 的API获取你想要的属性方法等等,那Swift呢?是不是也和OC一样呢?       这个问题在我看Swift的时候也有想过,带着这个问题就总结出了今天这篇文章。       先说说这个Runtime,在自己之前的文章中有总结过关于OC的Runtime以及它API的一些基本的方法和在项目中
Mr.RisingSun
2018/02/06
5K0
Swift Runtime ?
Swift基础语法(二)
我们之前介绍的数组Array、字典Dictionary等,都是值类型,而函数是引用类型。
拉维
2020/06/02
2.3K0
Swift-MVVM 简单演练(一)
Swift-MVVM 简单演练(二) Swift-MVVM 简单演练(三) Swift-MVVM 简单演练(四) 前言 最近在学习swift和MVVM架构模式,目的只是将自己的学习笔记记录下来,方便自己日后查找,仅此而已!!! 本来打算一篇全部搞定的,但是简书每篇文章只能写大约不超过15000字的内容,因此只能分开写了。 如果有任何问题,欢迎和我一起讨论。当然如果有什么存在的问题,欢迎批评指正,我会积极改造的! ---- 这篇文章都写啥 自定义NavgationBar 抽取便利构造函数 初步的下拉刷新/上
用户1890628
2018/05/10
10.6K0
27.Swift学习之与OC混编
在目前iOS开发语言从Objective-C到Swift的过渡时期,开发中难免会碰到两种语言同时存在的情况,如果在同一个项目中,两种语言并存,那么该项目就是一个混合项目。在混合项目中,就会存在语言相互调用的情况,那么一个是上世纪的“老人”,一个是初出茅庐的“少年”,它们的沟通是存在障碍的,如何才能在一个项目中让两种语言可以相互调用呢?Apple给我们做好了“桥接”工作,但是在Objective-C的项目中调用Swift与在Swift项目中调用Objective-C,处理的方式是不一样的,下面来进行一个简单的介绍。
YungFan
2018/12/26
1.3K0
module & Swift库
一个module是机器代码和数据的最小单位,可以独立于其他代码单位进行链接 通常,module是通过编译单个源文件生成的目标文件。例如:当前的test.m被编译成目标文件test.o时,当前的目标文件就代表了一个module 这里有一个问题,module在调用的时候会产生开销,当使用一个静态库的时:@import TestStaticFramework; 如果静态库中包含许多.o文件。这岂不是会导入很多module? 当然不会。在静态链接的时候,也就是静态库链接到主项目或者动态库,最终生成可执行文件或
ruochen
2021/12/05
2.2K0
Swift 4.0 新特性
WWDC 2017 带来了很多惊喜,在这次大会上,Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,虽然正式版要8月底9月初才会公布,但很多强大的新特性正吸引我们去学习它。根据大会上已经开放的新特性,先一睹为快。 体验 Swift 4包含在Xcode 9中,您可以从Apple的开发者门户下载最新版本的Xcode 9(您必须拥有一个活跃的开发者帐户)。 每个Xcode测试版将在发布时捆绑最新的Swift 4快照。在阅读时,您会注意到[SE-xxxx]格式的链接。 这些链接将带您到相关的Swif
xiangzhihong
2018/02/06
1.8K0
Swift 4.0 新特性
Swift中的命名空间
命名空间namespace在C++、C#里面是一个常见概念,Swift中也引入了这样一个机制,下面来探索一下这个命名空间的来龙去脉。
YungFan
2018/12/26
2.5K0
相关推荐
Swift基础语法(三)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验