Swift基本语法学习笔记

Swift与OC的不同点

  • 导入框架的方式
    • OC使用#import <UIKit/UIKit.h>
    • Swift使用import UIKit
  • 定义标识符的方式
    • Swift中定义标识符,必须指定该标识符是一个常量还是一个变量
  • 语句结束后的标志
    • Swift可以不用分号";"分割(只限于一行有一条语句时)
    • OC需要分号进行分割
  • 打印语句
    • 直接使用print()语句进行打印
    • OC中使用NSLog()语句进行打印

常量和变量的使用注意

  • 优先使用常量
  • 常量的本质:保存的时常量的内存地址,不可以修改,但可以通过内存地址拿到对象内部属性进行修改

Swift中的类型推导

在定义一个标识符,如果有直接赋值,那么会根据赋值的类型推导出前面标识符的类型,所以后面的类型可以省略

Swift中没有隐式转换,所以只有相同类型之间才可以进行运算

显式类型转换:Int(),Double()等

逻辑分支

if条件判断可以不要括号,没有非0即真的概念

  • OC中BOOL的值为YES/NO
  • Swift中的布尔Bool类型的值为true/false

guard的使用,适合多层if嵌套,使用guard代替,该语法是自Swift 2.0以后推出的.作用和if相同,但是可读性比if好.

switch的用法:

  • switch可以不跟()
  • case语句结束后,不跟break,系统会默认添加
  • 如果希望一个case中出现case穿透,可以在case语句结束后跟上fallthrough
  • case后面可以跟多个条件,多个条件以","分割
  • switch可以判断浮点型
  • switch可以判断字符串
  • switch可以判断区间

swift中的区间表示:

  • a..<b 相当于数学上 [a, b)
  • a...b 相当于数学上 [a, b]
  • swift中没有全开区间的概念,即没有(a, b)的写法

swift中的for循环:

  • for后面的括号可以省略
  • swift3中已经移除了普通的for循环写法
  • forin写法:区间遍历
  • forin写法,如果不需要用到下标值,可以用下划线"_"省略

swift中的while循环

  • 在OC中,使用do while循环
  • 在swift中,使用repeat while循环

字符串

swift中的字符串为String类型,是个结构体.而OC中的NSString是对象,所以swift中的字符串类型比OC的效率高.

  • 定义字符串,可以不用指定String类型
  • 可以直接遍历字符串中的字符,使用for c in str.characters{}
  • 字符串的拼接
    • 直接使用str1+str2
    • 拼接其他标识符的字符串:使用(str)
    • 字符串的格式化:String(format:"%02d:%02d", arguments: [min, second])
  • 字符串的截取:可以先转换为OC的NSString类型,再进行截取
    • (urlString as NSString).substring(to: 3)
    • (urlString as NSString).substring(with: NSRange(location: 4, length: 5))
    • (urlString as NSString).substring(from: 10)

数组

  • 数组的定义:
    • 可变数组(使用let声明):let array = ["a", "b"]
    • 不可变数组(使用var声明):
      • var arrayM = Array()
      • var arrayM = [String]()
  • 对可变数组的操作:
    • 添加元素:arrayM.append("c")
    • 删除元素:arrayM.remove(at: 0)
    • 修改元素:arrayM[0] = "m"
    • 获取元素:arrayM[0]
  • 遍历数组:
    • for i in 0..<arrayM.count {}
    • for name in arrayM {}
    • for i in arrayM[0..<2] {}
  • 数组的合并:
    • swift中,如果两个数组类型是完全一致的,才可以进行相加合并.

字典

  • 字典的定义:
    • 不可变字典(let)
      • 注意:在swift中无论是数组还是字典,都使用[],但是如果[]中存放的是元素,编译器会认为是一个数组.如果[]中存放的是键值对,编译器会认为是一个字典.
      • let dict = ["key" : "value"]
    • 可变字典(var)
      • var dictM = Dictionary<String, AnyObject>()
      • var dictM = [String : AnyObject]()
      • 注意:一般在指定数据类型时,使用AnyObject,在声明变量类型时使用NSObject.
  • 对可变字典的操作:
    • 添加元素:dictM["newKey"] = "newValue"
    • 修改元素:dictM["key"] = "newValue",如果存在key,则覆盖该key之前的value,如果不存在key,则直接添加.
    • 删除元素:dictM.removeValue(forKey: "key")
    • 获取元素:dictM["key"]
  • 遍历字典:
    • 遍历所有的key:for key in dictM.keys {}
    • 遍历所有的value:for value in dictM.values {}
    • 遍历所有的key/value: for (key, value) in dictM {}
  • 合并字典:
    • 注意:即使两个字典的类型一致,也不能进行相加合并
    • 如果必须进行合并,可以遍历一个字典,将其逐个添加到另外一个字典中.

元组

元组一般用于函数的返回值,其与数组和字典功能类似,但是写法更为直观,所以swift中新增了元祖的类型.

  • 元组的基本写法:let userInfo = ("name", 18, 1.8)
    • userInfo.0
  • 给每一个元素起别名:let userInfo = (name: "name", age: 18, height: 1.8)
    • userInfo.name
  • 别名就是元组变量的名称
    • let (name, age, height) = ("name", 18, 1.8)
    • 直接使用name,age,height即可获取元组中元素的值

可选类型

可选类型的作用:当声明一个变量为String类型,而想要给它赋值为nil,需要使用可选类型.

  • 定义方式:
    • 方式一:基本定义方式,不常用,var name: Optional = nil
    • 方式二:语法糖,常用,var name: String? = nil
  • 给可选类型赋值:name = "abc"
    • 在使用可选类型时,拿到optional(具体的值)
  • 强制解包:
    • 通过在变量后使用"!"来进行强制解包
    • 注意:强制解包是非常危险的过程,在强制解包时,如果里面没有值,程序会发生崩溃.
    • 严谨的解包方式:if name != nil {}
  • 可选绑定:
    • 如果name不等于nil,则解包name,并且将解包后的值赋值给新值
    • 方式一(不常用):if let tempName = name {}
    • 方式二(常用):if let name = name {}
    • 以上操作其实可以分为两步:
      • 首先判断name是否有值
      • 如果有值,则进行强制解包(系统会默认处理),并且将解包后的值赋给前面的常量,并执行大括号里面的代码
      • 如果没有值,则不进行强制解包,同时也不执行括号里面的代码

可选类型的应用场景

在使用一个字符串创建URL类型的常量时,需要使用可选类型

因为如果字符串中包含中文时,创建的URL对象可能为空

在使用的时候,需要对可选类型进行判断,此时可以使用可选绑定,在大括号内创建NSURLRequest对象

函数

在OC中叫做方法,在swift中叫做函数

  • 没有参数,没有返回值
    • func about() -> Void {}
    • func about() {}
  • 没有参数,有返回值
    • func readMessage() -> String {}
  • 有参数,没有返回值
    • func callPhone(phoneNum : String) -> Void {}
    • func callPhone(phoneNum : String) {}
  • 有参数,有返回值
    • func sum(num1: Int, num2: Int) -> Int {}

函数的注意点

  • 注意一:内部参数和外部参数
    • 内部参数:在函数内部可以看到的参数就是内部参数,默认情况下所有的参数都是内部参数
    • 外部参数:在函数外部可以看到的参数名称就是外部参数,在swift3之前默认从第二个参数开始既是内部参数又是外部参数,但是从swift3开始,默认第一个内部参数也是外部参数.
  • 注意二:swift中的默认参数
    • func makeCoffe(coffeName: String = "雀巢") -> String {}
    • 在调用函数是,如果没有传递某个参数的值,swift会根据函数的声明,自动添加默认参数的值.
  • 注意三:可变参数
    • func sum(num: Int...) -> Int {}
  • 注意四:指针类型
    • swift函数参数,默认是值传递,在函数中直接交换两个参数的值,调用函数后,参数的值并不会发生改变.
    • func swapNum(m: inout Int, n: intout Int) {}
    • 调用时:swapNum(m: &m, n: &n)
  • 注意五:函数的嵌套使用(用的不多,了解即可)
    • 在函数内部,可以声明新的函数,如果不调用,则不会执行函数内的代码.
    • 只有在调用了函数,才会执行,哪里调用就在哪里执行.

Swift中类的注意事项

  1. 类的定义
  • 可以不继承任何类:class Person {}
  • 可以继承NSObject:class Person : NSObject {}
  • 不继承父类,可以使自定义的类更加轻量级.如果需要使用到NSObject中的属性或方法,则需要继承,比如使用KVC对属性进行赋值
  • 注意:任何一个类,都要保证它里面的属性,在类初始化的时候要有一个默认值.
  1. 创建类对应的对象
  • let p = Person()
  • let p: Person = Person()
  1. 给类的属性赋值
  • 可以通过点语法直接赋值
  • 也可以通过KVC,调用类对象的setValuesForKeys()方法
  1. 可以重写setValue...forUndefinedKey方法,那么字典中没有的字段可以在类中没有对应的属性,程序也不会报错.
  2. 如果要写的某一个方法是对父类方法的重写,那么必须在该方法前加上override关键字

定义Swift类中的属性

在swift中,声明的类属性都需要进行初始化,类属性分为三类:

  • 存储属性:
    • var age: Int = 0
    • var mathScore: Double = 0.0
    • var chineseScore: Double = 0.0
  • 计算属性:
    • 通过别的方式计算到结果的属性,称之为计算属性
    • var averageScore: Double { return (mathScore + chineseScore) * 0.5 }
  • 类属性:
    • 类属性是和整个类相关的属性,而且是通过类名进行访问
    • 在生成单例的时候,会用到类属性
    • static var courseCount: Int = 0

给类属性赋值:Student.courseCount = 2

创建对象:let stu = Student()

给对象的属性赋值:stu.age = 10

直接使用计算属性:let averageScore = stu.averageStudent

在swift开发中,如果使用当前对象的某一个属性,或者调用当前对象的某一个方法时,可以直接使用,不需要加self.但是在产生歧义的情况下,还是需要加上self的.

Swift中类的构造方法

swift中类的构造函数和OC中的初始化方法功能相同,只是写法不同.

在构造函数中,如果没有明确super.init(),那么系统会帮助调用super.init()

  • 自定义构造函数:
    • 参数非字典类型:init(name: String, age: Int) {}
    • 参数为字典类型:
      • 可以直接遍历字典,在遍历字典的时候,需要判断可选类型,然后转换可选类型,再使用可选绑定,对属性进行赋值
      • 也可以直接使用KVC,但是在调用setValueForKeys()前,需要调用父类的初始化函数super.init(),虽然系统会默认调用该函数,但是在自定义构造函数尾部才去调用,所以需要首先调用super.init().
      • 在使用KVC的时候,也需要重写setValue(forUndefinedKey)方法,以便处理类中没有定义key的属性.

属性监听器

class Person: NSObject {// 属性监听器var name : String? {// 属性即将改变时进行监听willSet {print(name)print(newValue)}// 属性已经改变时进行监听didSet {print(name)print(oldValue)}}
}

回顾OC中的block

使用block模拟网络请求中的回调

  • 自定义一个网络请求的工具类HttpTool,提供loadData方法
- (void)loadData:(void (^)(NSString *))callBack
{dispatch_async(dispatch_get_global_queue(0, 0), ^{NSLog(@"发送网络请求:%@", [NSThread currentThread]);dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"拿到数据,并且进行回调:%@", [NSThread currentThread]);callBack(@"json数据");});});
}
  • 在ViewController中通过点击屏幕,在ViewController中拿到block返回的数据
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{/*__weak修饰的弱引用,如果指向的对象销毁,那么指针会立马指向nil(0x0)__unsafe_unretained修饰的弱引用,如果指向的对象销毁,那么指针依然指向之前的内存地址,很容易产生'野指针'/'僵尸对象'*/__weak ViewController *weakSelf = self;[self.tools loadData:^(NSString *jsonData) {// NSLog(@"在ViewController拿到数据:%@", jsonData);weakSelf.view.backgroundColor = [UIColor redColor];}];
}

闭包

闭包的写法:(参数列表) -> (返回值类型)

weakself?.view

  • 如果前面的可选类型,没有值,后面所有的代码都不会执行
  • 如果前面的可选类型,有值,系统会自动将weakself进行解包,并且使用weakself

闭包解决循环引用的三种方式:

  • 方式一(写法比较复杂):使用weak var weakSelf = self
    • 注意:必须使用var来声明,因为self可能会发生变化,如果使用let声明,编译器会报错.
  • 方式二(比较危险,当self指向nil时,可能会发生崩溃):tools.loadData {[unowned self] (jsonData) -> () in ... }
  • 方式三(常用写法):tools.loadData {[weak self] (jsonData) -> () in ... }

尾随闭包:如果闭包作为方法的最后一个参数,那么闭包可以将()省略掉

  • 普通写法:tools.loadData ({[weak self] (jsonData) -> () in ... })
  • 尾随闭包的写法一:tools.loadData() {[weak self] (jsonData) -> () in ... }
    - 但是闭包中可以直接使用self,而不需要进行解包
  • 尾随闭包的写法二(系统默认写法):tools.loadData {[weak self] (jsonData) -> () in ... }

注意:swift中的deinit()方法相当于OC中的dealloc方法,当对象销毁时,会调用该函数.

  • OC中使用__weak修饰self,当对象销毁时,self将指向nil(0x0)

  • OC中使用__unsafe__unretain修饰self,当对象销毁时,self仍指向原内存地址,会产生"野指针"错误或"僵尸对象",这个写法相当于swift中的unowned.

懒加载

  • 懒加载的介绍

    • swift中也有懒加载的方式.
    • 苹果的设计思想:希望所有的对象在使用时才真正加载到内存中
    • 和OC不同的是,swift有专门的关键字来实现懒加载
    • lazy关键字可以用于定义某一个属性懒加载
  • 懒加载的使用

    • 格式:lazy var 变量: 类型 = {创建变量的代码}()
// 懒加载的本质是,在第一次使用的时候,执行闭包
// 将闭包的返回值赋值给属性
// lazy的作用是只会赋值一次
lazy var array: [String] = {() -> [String] inreturn ["abc", "def", "ghi"]
}()

也可以写成下面这种方式

lazy var array: [String] = {return ["abc", "def", "ghi"]
}()

转载于:https://www.cnblogs.com/coderwjq/p/6004981.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/270634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络知识:IP地址的概念以及IPV4和IPV6的区别

小伙伴们看到上面的机房了吗&#xff1f;成千上万台服务器他们都少不了一个小小的IP地址&#xff0c;每台服务器都配置了一个或多个IP。今天电脑学习微信公众号小编就带大家详细了解下IP地址都是什么&#xff1f; IP地址&#xff08;Internet Protocol Address&#xff09;是指…

新安装Win10操作系统有必要设置的几个技巧

目录 1、控制面版、回收站、网络等图标放到桌面 2、找回Win10系统删除提示框 3、关闭电脑休眠并删除hiberfil.sys 睡眠缓存文件 3、关闭Microsoft Store自动更新 4、卸载Win10自带的软件 5、关闭自动播放功能 6、删除离线地图文件并禁止更新离线地图 新安装Win10操作系统有必要…

apk私钥_获取APK证书MD5、SHA1、SHA256等秘钥

一1.先把apk解压2.在META_INF目录下找到xxx.RSA文件3.确保安装了jdk并且正确配置了环境变量4.cmd中执行keytool -printcert -file xxxx.RSA目录image.png二1.确保安装了jdk并且正确配置了环境变量。2.cmd中执行keytool -printcert -jarfile xxx.apk运行效果如下&#xff1a;ima…

查看某个端口的进程 lsof -i:端口号

查看某个端口的进程 lsof -i:端口号

10.27 noip模拟试题

1.铺瓷砖&#xff08;tile.cpp/c/pas&#xff09;【问题描述】有一面很长很长的墙。 你需要在这面墙上贴上两行瓷砖。 你的手头有两种不同尺寸的瓷砖&#xff0c;你希望用这两种瓷砖各贴一行。瓷砖的长可以用分数表示&#xff0c;贴在第一行的每块瓷砖长度为 AB &#xff0c;贴…

Windows操作系统装机必备软件,值得收藏

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

最详细的Mac下安装nacos教程来了

什么是 Nacos 概览 欢迎来到 Nacos 的世界&#xff01; Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。…

android php mysql json 查询_android php mysql json

$con mysql_connect("localhost", "db163810_f", "1e6969e2");if (!$con){die(不能建立连接: . mysql_error());}$db_selected mysql_select_db("db163810",$con);mysql_query("SET NAMES utf8");if (!$db_selected){die…

纯css改变下拉列表select框的默认样式

下列CSS就可以解决&#xff0c;原理是将浏览器默认的下拉框样式清除&#xff0c;然后应用上自己的&#xff0c;再附一张向右对齐小箭头的图片即可。 select {/*Chrome和Firefox里面的边框是不一样的&#xff0c;所以复写了一下*/border: solid 1px #000;/*很关键&#xff1a;将…

电脑软件:推荐5款实用的效率软件

目录 1、图片管理神器-Image Tuner 2、系统维护神器-Dism 3、桌面效率神器-蜂窝桌面整理 4、键鼠模拟软件-按键精灵 5、书签管理神器-Toby for Chrome 今天小编大家推荐5款实用的效率神器&#xff0c;希望对大家能有所帮助&#xff01; 1、图片管理神器-Image Tuner 1000张图片…

SpringCloud版本说明

SpringCloud包含了众多子项目&#xff0c;每一个子项目发布时间不一定一致&#xff0c;所以采用了伦敦地铁站为版本说明&#xff0c;而不是数字。并且从A开始是第一个发布版&#xff0c;B是第二个&#xff0c;以此类推。 SpringCloud版本SpringBoot版本Greenwich(格林威治)2.1…

JQuery中$.ajax()方法参数详解

url: 要求为String类型的参数&#xff0c;&#xff08;默认为当前页地址&#xff09;发送请求的地址。 type: 要求为String类型的参数&#xff0c;请求方式&#xff08;post或get&#xff09;默认为get。注意其他http请求方法&#xff0c;例如put和 delete也可以使用&#xff0…

数据库:Redis数据库优点介绍

1、速度快 不需要等待磁盘的IO&#xff0c;在内存之间进行的数据存储和查询&#xff0c;速度非常快。当然&#xff0c;缓存的数据总量不能太大&#xff0c;因为受到物理内存空间大小的限制。 2、支持多种数据库类型 丰富的数据结构 除了string之外&#xff0c;还有list、hash、…

bat-bat-bat (重要的事情说三遍)

去年noip前prey亲授&#xff0c;当时就觉得这是个好东西&#xff01;非常好&#xff01;然后我就没学会。接着最近被安利小红的bat&#xff01;&#xff01;&#xff01; 小红bat&#xff01;&#xff01;&#xff01; get&#xff01;&#xff01;&#xff01;谢小红&#xff…

mysql开方_MySQL数学函数的实际用法

此文章主要向大家描述的是MySQL数学函数的实际用法以及在实际操作中值得大家注意的问题&#xff0c;MySQL数学函数是MySQL函数中经常被用到的&#xff0c;所以对其有一定的了解还是有你有所帮助的。ABS (number2 ) //绝对值BIN (decimal_number ) //十进制转二进制CEILING (num…

POJ 2323 贪心

题意&#xff1a; 思路&#xff1a; 贪 贪 贪 如果当前的c>之前的cs 那么之前的合适 一直贪下去就好了 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define int long long int n,s,rec1,c[105…

mysql调度触发器,MySQL触发器:达到某个datetime时更新

I want to create a MySQL trigger that updates a table everytime one of the datetime rows in a different table reaches a datetime lower than now.How would I accomplish this? Is that even possible?To illustrate:table_1 table_2-------- ------------------- -…

实验二简化版C语言中文理解程序文法

<程序>&#xff1a;&#xff1a;begin<语句串>end <语句串>&#xff1a;&#xff1a;<语句>{;<语句>} <语句>&#xff1a;&#xff1a;<赋值语句> <赋值语句>&#xff1a;&#xff1a;ID<表达式> <表达式>&#x…

常用软件:推荐七款装机必备的软件

目录 1.桌面日历 2.FileViewPro——万能文件查看器 3.FSCapture 4.天若OCR 5.Gif Cam 6、Sticky Notes 7、PotPlayer 1.桌面日历 工作之后事情越来越多&#xff0c;一款好用的桌面日历可以让帮你掌握全局&#xff01; 点击每个窗格 可以直接添加待办事项。 完成的事件可以划横…