洋仔的博客 洋仔的博客
首页
  • 个人心法总结

    • 价值心法
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • iOS基础知识
  • 前端
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 投资体系
  • 毛选
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

洋仔

奋斗的小青年
首页
  • 个人心法总结

    • 价值心法
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • iOS基础知识
  • 前端
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 投资体系
  • 毛选
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

  • 博客搭建

  • iOS基础知识

    • iOS底层相关

    • Runloop系列

    • Runtime系列

    • 内存管理系列

    • Block系列

    • 线程系列

    • KVC跟KVO系列以及通知中心

    • UI系列

    • 离屏渲染系列

    • 组件化系列跟架构

    • OC跟webview交互系列

    • 持久化系列

    • APP编译系列

    • APP性能优化系列

    • cocoapods系列

    • swift系列

      • swift跟OC对比
      • swift面试
        • swift和OC的主要区别:
          • 口语回答
          • OC与Swift的区别一(文件结构)
        • OC与Swift的区别一(常量、变量、运算符)
          • OC与Swift的区别三(条件语句)
          • OC与Swift的区别四(条件语句)
          • OC与Swift的区别五(函数)
      • swiftUI面试
    • Git系列

    • 网络相关

    • 三方库系列

    • 系统原理

    • 总结系列

    • 算法系列

    • 数据结构系列

  • 前端

  • 技术
  • iOS基础知识
  • swift系列
洋仔
2023-09-29
目录

swift面试

# 面向对象开发核心&& 向协议开发核心

面向对象开发核心是: 封装-继承-(多态),弊端:继承链很长,代码高度耦合 面向协议开发核心是: 模块化(组件化)

OC不能面向协议开发的原因是,OC中的协议只能有方法的声明,不能有方法的实现,而Swift可以通过协议拓展,来声明方法和实现方法,所以swift可以进行面向协议编程。

protocol Emitterable {
     
}
//协议拓展
extension Emitterable{
    
    /// 方法的声明和实现
    func start() {
    }
  }
1
2
3
4
5
6
7
8
9
10

面向协议开发应用:

很多UIView会通过xib进行描述, 而我们经常需要从一个xib中加载UIView, 抽取单独的协议, 需要从xib中加载类, 只需要遵守协议即可,而不需要继承自父类,再转为子类。

使用loadFromNib方法,从xib中加载UIView,

protocol NibLoadable {
	
}

extension NibLoadable where Self : UIView {
    static func loadFromNib(_ nibname : String? = nil) -> Self {
        let loadName = nibname == nil ? "\(self)" : nibname!
        return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)?.first as! Self
    }
}


1
2
3
4
5
6
7
8
9
10
11
12

一般会使用where Self对可遵守协议的类型进行限制。此处UIView要求的子类才可遵守该协议,并且可以直接使用UIView相关的属性和方法。

# swift和OC的主要区别:

OC面向对像编程,swift面向协议编程 OC 中协议主要用来对象件传值,swift 不仅可以用来传值还可以定义属性方法,支持拓展

# 口语回答

swift 不分 .h 和 .m ,只有一个 .swift 文件,文件的数量和后缀与 OC 不同 swift引入了命名空间,从此不用再import其他文件 swift 语言代码语句后不需要加";" swift 语言比较简短简洁 swift 定义变量或常量使用 var 或 let 字符串,swift “”,OC @“” switch 语句,swift 可以是各种数据类型,OC 中的switch语句,不能判断对象类型, 只能判断基本类型中的整数 判断语句 if let,gurad 可选(Optional)类型。swift增加了可选类型处理值缺失的情况。nil的含义不同,可选类型比 Objective-C 中的 nil 指针更加安全。 OC 中定义的类,都是直接或者间接继承NSObject类的,swift 可以直接定义一个基类,不继承任何类 swift元祖类型,支持运算符重载 swift支持泛型,OC只支持轻量泛型 swift函数嵌套 swift的协议不仅可以被类实现,还可以被struct和enum实现 swift是静态语言,OC是动态语言。 swift偏重于面向协议的编程,OC面向对象编程。 swift注重值类型,OC注重引用类型。 swift支持函数式编程

# OC与Swift的区别一(文件结构)

  1. 文件后缀名

oc的文件后缀名为:头文件.h 主体文件.m

swift文件后缀名为:.swift

  1. 代码分隔符

oc中使用分号;作为代码分隔符

swift中无需使用代码分隔符,以行作为代码分隔,如一行内有多行代码,则各行代码之间同样需使用分号;分隔

  1. main函数

oc的main函数为程序入口,其函数定义与c语言类似

swift没有main函数,其代码是至上而下运行,第一行代码即为程序入口

不像C语言和OC语言一样都必须有一个主函数main()作为程序的入口,swift程序从第一句开始向下顺序执行,一直到最后。(swift将全局范围内的首句可执行代码作为程序入口,swift也有main函数,只是不用我们自己编写。)

# OC与Swift的区别一(常量、变量、运算符)

  1. 常量与变量声明

oc的变量声明使用 类型 变量名 = 变量值的方式,其中类型为系统内置数据类型或自定义类型,变量名需由英文字母开头且不能包含特殊字符

swift变量声明使用 var 变量名 = 变量值的方式,其中变量名可以使用任何你喜欢的字符,甚至是表情符号emoji等

oc常量声明使用const放在变量定义前即为声明常量,如:const NSString *str = @"Hello";

swift常量声明使用 let 常量名 = 常量值的方式,同样可以使用任何你喜欢的字符作为常量名

swift 可以自动推断出常量与变量的数据类型,当然也可以使用“:数据类型”的方式指定其具体数据类型,如 let age:Int = 10

PS:swift严格要求变量在使用前必须进行初始化,如上所示,必须给定变量值,而oc则不强制

  1. 整数

swift提供了8、16、32、64位有符号和无符号整数,如UInt8、Int64等,每一种类型都有一个min和max可调用,如UInt8.min、UInt8.max等。

  1. 浮点数

swift浮点数可以用十进制和十六进制2种进制来表示

十进制:let d1=12.5或let d2=0.125e2 后缀e2代表e前面部分乘以10的2次方

十六进制:let d3=0xC.8p0 0x前缀表示后面是十六进制,p0代表前面整个数字乘以2的0次方 且指数部分(px)必须存在

  1. 数字格式

swift中允许在数字中间加入符号_,以增加可读性,并不会影响原来数据,如 let money = 100_0000 还是表示100000

swift中还允许在数字前面加入0,以增加可读性,并不会影响原来数据,如 let money = 001_000_000还是表示1000000

而这些在oc中是不允许的

  1. 字符串

oc中使用@""来表示字符串

swift使用""来表示字符串,拼接字符串直接使用+将两个字符串或字符串变量进行拼接运算即可,如var str1="abc";var str2="def";var str3=str1+str2;

oc使用stringFormat方法进行字符串格式化,可以将其他非字符串值插入字符串中进行格式化

swift使用“()”将其它非字符串插入字符串中,如:let hand=2;var age=20;let str="我今年(age)岁了,有(hand)只手",也可以使用String(age)进行转换,并用+进行字符串拼接,如let str="我今年"+String(age)+"岁了,有"+String(hand)+"只手"

  1. 数据类型转换

swift类型转换使用“数据类型(原数据)”进行类型转换,如let money1=100;let money2=50.5;let totalMoney=Double(money1)+money2;

  1. 运算符

oc赋值运算符返回该变量值,如 int a = 0;int b = a = 10;其实a=10返回10赋值给了b

swift赋值运算符没有返回值

oc求模运算只支持整数求模运算

swift求模运算支持浮点数求模运算,如8%2.5=0.5,因为8=2.5*3+0.5

oc中bool有两个值 YES NO 其实根本0为假,非0都代表真

swift中bool有两个值false true 且只有false和true 0与非0在任何场合都不代表bool值,比如if(10)这种写法是错的

swift 比oc中多几种运算符

  1. 1闭合范围运算符

a...b [a,b]包含a,b

a..<b [a,b)包含a,不包含b

如for i in 0..<5{

printfln(i)

}

  1. 2溢出运算符

swift为整型计算提供了5个&开头的溢出运算符

&+ 溢出加

&- 溢出减

&* 溢出乘

&/ 溢出除

&% 溢出求模

如 let x = UInt8.max //x=255

let y = x &+1         //y=0

如 let x = UInt8.min //x=0

let y = y &- 1      //y=255

# OC与Swift的区别三(条件语句)

  1. swift中的switch结构

区别一:

oc中switch条件只可以放整数

swift中switch条件可以放几乎任何数据类型

区别二:

oc中每一个case中应有break,如果没有break,则会继续向下贯穿执行case直到碰见break跳出switch结构

swift中不需要在case分支最后添加break语句,该case分支执行完成后,会跳出switch结构

区别三:

oc中不是每个case后面必须有可执行语句,如果某个case分支中没有可执行语句和break,则该分支将会执行其下面最近的一个有可执行语句的分支中代码,以此实现多条件匹配

swift中每个case后面必须都有可执行语句,

ps:此区别是因为区别二的存在,swift中表示多条件匹配的情况使用的语法为,case后跟多个条件,用逗号隔开。

此外,swift的case中可以填写一个范围作为匹配条件,如case a...b:

区别三:

oc中switch中default不是必需的

swift中switch中default是必需的

swift中switch语句可以使用where来增加判断条件

如:

var point = (10,-10)

switch point{

case let(x,y) where x == y :

         //

  case let(x,y) where x == -y :

        //

   default :

//

}

swift中switch语句可以使用fallthrough关键字来执行贯穿操作,即执行完当前case后,会接着执行fallthrough后面的case活着default语句,类似于oc中case没有写break语句,但是使用了fallthrough,其后面的case条件中将不能定义常量或变量,即fallthrough后面的case条件不能使用类似上面代码中let (x,y) 这样的变量来接收point,否则会有语法错误。

# OC与Swift的区别四(条件语句)

12.条件语句的区别,此处只写区别,没有指出区别的其他方面oc与swift基本一致

12.1

oc中for if switch语句体如果只有一行代码,则{}可以省略

swift中for if switch语句体必须使用{} ,否则有语法错误

12.2for-in语法的区别:

//从1循环到3,包括3,即循环3次

for i in 1...3{

}

//如果不需要用到循环条件范围中的值,则使用_忽略该循环条件值,使其在循环体内不会创建局部变量

for _ in 1...3{

}

//循环条件值是常量,在循环体内不能改变

for i in 1...3{

i = 10   //此代码报错

}

# OC与Swift的区别五(函数)

13 函数

oc函数定义:

返回值类型 函数名(参数类型 参数名,参数类型 参数名){

}

swift 函数定义:

func 函数名(参数名:参数类型,参数名:参数类型) -> 返回值类型{

}

swift中没有返回值的函数有三种写法:

13.1

func 函数名(参数名:参数类型,参数名:参数类型) -> Void{

}

13.2

func 函数名(参数名:参数类型,参数名:参数类型) -> (){

}

13.3

func 函数名(参数名:参数类型,参数名:参数类型){

}

swift中没有行参的函数函数名后面的小括号也不能省略

返回元组的函数定义:

func 函数名(参数名:参数类型,参数名:参数类型) -> (元素名称:元素类型,元素名称:元素类型){

}

swift中的外部参数名

func 函数名(外部参数名 形式参数名:参数类型,外部参数名 形式参数名:参数类型) -> 返回值类型{

}

//形式参数名前面加上# ,则外部参数名与形式参数名相同

func 函数名(#形式参数名:参数类型,#形式参数名:参数类型) -> 返回值类型{

}

当调用增加了外部参数名的函数,在调用时,则编译器会自动生成带有外部参数名的调用,并且外部参数名在调用时必须加上且参数顺序必须与定义时一致,这样可以增加调用者对参数的可读性

如

func addPerson(person_name:String,person_age:Int){

}

addPerson(person_name:"jack",person_age:28)

swift中的默认参数值

func 函数名(外部参数名 形式参数名:参数类型 = 参数默认值,外部参数名 形式参数名:参数类型) -> 返回值类型{

}

带有默认值的函数调用时,有默认值的参数可以不传值,且如果不指定有默认值行参的外部参数名,swift会自动生成一个与其行参名相同的外部参数名,在有默认值的行参参数名前加上_,则调用时不需要写其外部参数名

注意: oc中参数在函数体内是可以修改其值的,因为其作用类似于局部变量。但是在swift中,参数默认都是常量参数,不能在函数体内修改参数值。如果需要在函数体内修改参数值,则需要定义变量参数,即在参数名前加var关键字即可。

编辑 (opens new window)
上次更新: 2024/10/23, 23:26:17
swift跟OC对比
swiftUI面试

← swift跟OC对比 swiftUI面试→

最近更新
01
数组
10-25
02
数组双指针系列之对撞指针
10-25
03
数组双指针系列之快慢指针
10-25
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式