switf 2.0增加了一个新的关键字来实现递归枚举。下面的例子是一个枚举类型,它在Node条件下有两个相关联的值类型T和List:

enum List{ case Node(T,List)}什么关键字可以实现递归枚举?

  答案:indirect关键值可以允许递归枚举,代码如下:

  enum List{ indirect case Cons{T,List)}


 

描述一种在Swift中出现循环引用的情况,并说明怎么解决。

  答案:循环引用出现在当两个实例对象相互拥有强引用关系的时候,这会造成内存泄露,原因是这两个对象都不会被释放。只要一个对象被另一个对象强引用,

  那么该对象就不能被释放,由于强引用的存在,每个对象都会保持对方的存在。

  解决方式:用weak或者unowned引用代替其中一个的强引用,来打破循环引用。


 

  

UInt类型是用来存储无符号整形的。下面的代码实现了一个有符号整型转换的初始化方法:

init(_ value:Int)

然而,在下面的代码中,当你给一个负值的时候,它会产生一个编译时的错误:

  let number = UInt(-1)

我们知道负数的内部结构是使用二进制补码的正数,在保持这个负数内存地址不变的情况下,如何把一个负整数转换成一个无符号的整数?

  答案:使用下面的初始化方法:

  UInt(bitPattern:Int)


 

闭包是引用类型吗?

  答案:闭包是引用类型。如果一个闭包被分配给一个变量,这个变量复制给另一个变量,那么他们引用的是同一个闭包,他们的捕捉列表也会被复制。


 

 

你能通过extension(扩展)保存一个属性吗?请解释一下原因。

  答案:不能。扩展可以给当前的类型添加新的行为,但是不能改变本身的类型或者本身的接口。如果你添加一个新的可存储的属性,你需要额外的内存来存储新的值。扩展并不能实现这样的任务。


  

声明一个静态属性或者函数,我们常常使用值类型的static修饰符。下面就是一个结构体的例子:

  struct Sun{ static func illuminate(){}}

对类来说,使用static或者class修饰符,都是可以的。它们使用后的效果是一样的,但是本质上是不同的。能解释一下为什么不同吗?

  答案:static修饰的属性或者修饰的函数都不可以重写。但是使用class修饰符的,你可以重写属性或者函数。

  当static在类中应用的时候,static就成为class final的一个别名。

  例如:在下面的代码中,当你尝试重写illuminate()函数时,编译器就会报错;


 

 

在Objective-C中,一个常量可以这样定义:

  const int number = 0

  类似的Swift是这样定义的:

  let number = 0

  两者之间有什么不同吗?如果有,请说明原因。

  答案:const常量是一个在编译时或者编译解析时被初始化的变量。通过let创建的是一个运行时常量,是不可变的。它可以使用stattic或者dynamic关键字来初始化。谨记它的值只能被分配一次。


 

 

下面的功能特性都包含在Swift中吗?

1.泛型类

2.泛型结构体

3.泛型协议

  答案:Swift包含1和2特性。泛型可以在类,结构体,枚举,全局函数或者方法中使用。3是通过typealias部分实现的。typealias不是一个泛型类型,它只是一个占位符的名字。它通常是作为关联类型被引用,只有协议被一个类型引用的时候它才被定义。


 

Swift是面向对象编程语言还是函数式编程语言?

  Swift是一种混合编程语言,它包含这两种编程模式。它实现了面向对象的三个基本原则:

  •   封装
  •   继承
  •   多态    

  说道Swift作为一个函数式编程语言,我们就不得不说一下什么是函数式编程。有很多不同的方法去定义函数式编程语言,但是他们表达的意义相同。

  最常见的定义来自维基百科:……它是一种编程规范……它把电脑运算当作数学函数计算,避免状态改变和数据改变。

  很难说Swift是一个成熟的函数式语言,但是他已经具备了函数式语言的基础。


 

 

对一个optional变量拆包有多少种方法?并在安全方面进行评价。

  答案:强制拆包 !操作符——不安全

     隐式拆包变量生命——大多数情况下不安全

     可选绑定——安全

     自判断链接(optional chaining)——安全

     nil coalescing运算符(空值合并运算符)——安全

     Swift2.0的新特性guard语句——安全

     Swift2.0的新特性optional pattern(可选模式)——安全


 

 

哪些情况下你不得不使用隐式拆包?说明原因。

对optional变量使用隐式拆包最常见的原因如下:

  1.对象属性在初始化的时候不能nil,否则不能被初始化。典型的例子是Interface Builder outlet类型的属性,它总是在它的拥护者初始化之后再初始化。在这种特定的情况下,假设它在Interface Builder中被正确的配置——outlet被使用之前,保证它不为nil。

  2.解决强引用的循环问题——当两个实例对象相互引用,并且对引用的实例对象的值要求不能为nil的时候。在这种情况下,引用的一方可以标记为unowned,另一方使用隐式拆包。

建议:除非必要,不要对option类型使用隐式拆包。使用不当会增加运行时崩溃的可能性。在某些情况下,崩溃可能是有意的行为,但有更好的方法来达到相同的效果,例如,通过使用fatalError()函数。


 

什么是泛型?泛型是用来解决什么问题的?

  答案:泛型是用来使类型和算法安全的工作的一种类型。在Swift中,在函数和数据结构中都可以使用泛型,例如类,结构体和枚举。

  泛型一般是用来解决代码复用的问题。常见的一种情况是,你有一个函数,它带有一个参数,参数类型是A,然而当参数类型改变成B的时候,你不的不复制这个函数。


 

在Swift中,什么时候用结构体,什么时候用类?

  答案:在Swift中,类和结构体有许多不同的特性。下面是两者不同的总结:

  类支持继承,结构体不支持。

  类是引用类型,结构体是值类型

  并没有通用的规则决定结构体和类哪一个更好用。一般的建议是使用最小的工具来完成你的目标,但是有一个好的经验是多使用结构体,除非你用了继承和引用语义。

  注意:在运行时,结构体在性能方面更优于类,原因是结构体的方法调用是静态绑定,而类的方法调用是动态实现的。这就是尽可能得使用结构体代替类的又一个好的原因。


 

什么是optional类型,它是用来解决什么问题的?

  答案:optional类型被用来表示任何类型的变量都可以表示缺少值。在Objective-C中,引用类型的变量是可以缺少值的,并且使用nil作为缺少值。基本的数据类型如int或者float没有这种功能。

  Swift用optional扩展了在基本数据类型和引用类型中缺少值的概念。一个optional类型的变量,在任何时候都可以保存一个值或者nil。


 

下面的代码输出是什么?并说明理由。

  var thing = "cars"    

  let clousure = {[thing] in print("I love (thing)")}

  thing = "airplanes"

  closure()

  答案:输出的是:I love cars。当闭包被声明的时候,捉捕列表就复制一份thing变量,所以被捕捉的值并没有改变,即使你给thing赋予了一个新值。

  如果你要忽视闭包中捕捉列表的值,那么编译器引用那个值而不是复制。这种情况下,被引用变量的值的变化将会反映到闭包中,正如下面的代码所示:

  var thing = "cars"

  let closure = { print("I love (thing)")}

  thing = "airplanes"

  Prints"I love airplanes"


 

 

思考下面的代码:

  代码:

  var optional1:String? = nil

  var optional2:String? = .None

  nil和.None有什么不同?optional1和optional2有什么不同?

  答案:两者没有什么不同。

  Optional.None(简称.None)是optional变量值初始化的标准方法,而nil只是.None语法的一种修饰。事实上下面语句输出是正确的:

  nil == .None//On Swift1.x this doesnt compile.You need Optional.None记住枚举类型的Optional下的None:

  enum Optional{ case None case Some(T)}


 

 

下面的代码创建了两个类Address和Person,并且创建了两个实例对象分别代表了Ray和Brain.

  class Address{ var fullAddress:String 

  var city:String

  init(fullAddress:String,city:String){ self.city = city}}

  class Person{ var name:String var address:Address

  init(name:String,address:Address){ self.name = name

  self.address = address}} 

  var headquarters = Address(fullAddress:"123 Tutorial Street",city:"Appletown")

  var ray = Person(name:"Ray",address:headquarters)

  var brian = Person(name:"Brian",address:headquarters)

  假设Brain搬家到街对面的建筑物里,那么你会这样更新他的地址:

  

  brian.address.fullAddress = "148 Tutorial Street"

  这样做将会发生什么?错误出在什么地方呢?

  答案:Ray同样会搬家到新的建筑物里面。Address是一个引用类型类,所以无论你是通过ray或者brain访问headquarters,访问都是同一个实例化对象。headquarters对象的变化也会引起ray和brain的变化。你能想象如果Brain收到Ray的邮件或者相反Ray收到Brain的邮件,将会发生什么?解决方案是创建一个新的Address对象赋值给Brain或者把Address声明成为结构体而不是一个类。


 

 

下面的代码是把数组里面的名字按字母的顺序排序,看上去比较复杂。尽最大的可能简化闭包里的代码。

  let animals = ["fish","cat","chicken","dog"]

  let sortedAnimals = animals.sort{ (one:String,two:String)->Bool in return one < two}

  答案:第一个简化的参数。系统的参数类型推断功能,可以计算出闭包里面参数的类型,所以你不必定义参数的类型推断功能,可以计算出闭包里面参数的类型,所以不必定义参数的类型:

  let sortedAnimals = animals.sort{(one,two)->Bool in return one < two}

  函数返回值也可以被推断出来,所以简化掉,代码变为:

  let sortedAnimas = animals.sort{(one,two)in return one < two}这个$i符号可以代替参数名字,代码进一步简化为:

  let sortedAnimals = animals.sort{return $0 < $1}

  这简化很多了,但是我们我们不能止步于此!

  对于字符串,有一个定义如下的比较函数:

  func Bool

  这个简单的小函数可以使你的代码简洁如下:

  let sortedAnimals = animals.sort(<)注意每一步的编译结果都相同,但是最后一步你的闭包里只有一个字符。


 

view1声明称var类型,view2声明let类型。这里有什么区别吗?下面的最后一行代能编译吗?

  代码:

  import UIKit

  var view1 = UIView()view1.alpha = 0.5

  let  view2 = UIView()view2.alpha = 0.5

  //最后一行代码能编译吗?

  答案:view1是个变量可以重新赋值给一个新的实例化的UIView对象。使用let你只赋值一次,所以下面的代码是不能编译的:

  view2 = view1//Error:view2 is immutable

  但是UIView是一个引用类型的类,所以你可以改变view2的属性,也就是说最后一行代码是可以编译的:

  let view2 = UIView()view2.alpha = 0.5//Yes!


 

回答下面swift问题?

  并说明原因。

  答案:tutorial1.difficulty的值是1,然而tutorial2.difficulty的值是2.

  在Swift中结构体是值类型,他们的值是复制的而不是引用。下面的一行代码意思是复制了tutorial1的值并把它赋值给tutorial2:

  var tutorial2 = tutorial1

  从这一行开始,tutorial2值得改变并不影响tutorial1的值。

  假如Tutorial是一个类,tutorial1.diffculty和tutorial2.diffculty的值将都会2.在Swift中类对象都是引用类型。tutorial1属性的任何改变将会反应到tutorial2上,反之亦然。


 

 

(Swift1.0及其之后的版本的问题)有什么更好的方法来写下面的for循环?

  前

  for var i = 0;i < 5;i++{ print("Hello!")

  后

  for _ in 0...4{ print("Hello!")}

  Swift实现了两个数组运算符closed operator和half-operator.前者包含数组中得所有值。例如:下面的例子包含从0到4得所有整数:

  0...4

  half-operator不包含数组中的最后一个元素,下面的例子会得到的结果和上面的一样:

  0..<5


 

 

为什么要在变量类型后面加个问号?

  用来标记这个变量的值是可选的。


 

 

用Swift定义一个数组和字典?

  let emptyArray = String[]()

  let emptyDictionary = Dicionary<String,Float>()


 

 

Swift中如何定义变量和常量?

  使用let来声明常量,使用var来声明变量


 

 

用Swift打印一段代码?

  print("hello,world")


 

 

Swift是一门安全语言吗?

  Swift是一门类型安全的语言,Optionals就是代表。Swift能帮助你在类型安全的环境下工作,如果你的代码中需要使用String类型,Swift的安全机制能阻止你错误的将Int值传递过来,这使你在开发阶段就能及时发现并修正问题。


 

 

举例说明Swift里面有哪些是Objective-C中没有的?

  Swift引入了在Objective-C中没有的一些高级数据类型,例如tuples(元组),可以使你创建和传递一组数值。Swift还引入了可选项类型

  (Optionals),用于处理变量值不存在情况。可选项的意思有两种:一是变量是存在的,例如等于X,二是变量值根本不存在。Optionals类似于Objective-C中指向nil的指针,但是适用于所有的数据类型,而非仅仅局限于类,Optionals相比于Objective-C中nil指针更加安全和简明,并且也是Swift诸多最强大功能的核心。


 

 

Swift支持面向过程编程吗?

  答案:它采用了Objective-C的命令参数以及动态对象模型,可以无缝对接到现有的Cocoa框架,并且可以兼容Objective-C代码,支持面向过程编程和面相对象编程


 

 

Swift的内存管理是怎样的?

  答案:Swift使用自动引用计数(Automatic Reference Counting,ARC)来简化内存管理


 

 

Swift比Objective-C有什么优势?

  答案:Swift全面优于Objective-C语言,性能是Objective-C的1.3倍,上手更加容易。


 

 

说说你认识的Swift是什么?

  答案:Swift是苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C共同运行于MAC OS和iOS平台,用于搭建基于苹果平台的应用程序。


 

 

CocoaPods如何适用于swift?

  答案:可能以类似的方式。Swift项目仍然是Xcode项目,并且支持多个target,但是有提升创建模块和自定义框架能力的潜在空间。有可能会重新改写CocoaPods以适应这个新特性。


 

 

下一步做什么?

  答案:这仅仅是版本1,苹果的目的非常清楚,他们将在该语言上进行迭代,所以你可以向苹果报告bug,要求新特性等等。在该版本正式发布之前,仍有很大的提升空间。


 

 

分号去哪里了?

  答案:分号在Swift中是可选的,不过出于易读性的目的,苹果建议你不要再使用分号了。但有时候仍会在Swift中使用分号,比如在循环语句中。


 

 

何时应该使用强引用,弱引用以及无主引用呢?

  答案:

  强引用:强引用会使得ARC保留实例直到不再需要它们。当移除所有强引用时,引用实例就会被释放。注意默认情况下强引用是隐式的,所以你不必显式地声明它。

  弱引用:你应该在独立生命周期的对象间使用弱引用。当为一个对象设置弱引用时,如果出于内存压力释放了对象,表示你不介意这一点。弱引用的值必须是一个变量,使用var定义,并且必须是使用?运算符的Optional类型。由于弱引用是可选的,所以你决不能以一个已经不存在的无效实例的引用来结束。当引用实例被释放时,ARC将会自动把引用设置为nil。

  无主引用:你应该为有相同生命周期的对象使用无主引用;比如当一个对象指向其自身,以及你希望避免一个retaincycle。无论何时只要引用有一个值就可以使用无主引用,但当你需要告诉ARC不要将它设置为nil时。无主引用的行为类似于Objective-C的unsafe_unretained。你要确保你不会在引用对象被释放后访问引用,这样会导致你的app崩溃。无主引用不能是可选的,不能被设置为nil。无主引用也是隐式解析。


 

 

我需要担心引用生命周期吗?

  答案:当然!当两个对象彼此之间是强引用时,仍能创建一个retain cycle。你可以使用Objective-C中一样的方法break这个retain cycle。有三个关键字用于声明引用类型,详情如下,弱引用和无主引用将解决你的引用生命周期问题。


 

 

Objective-C中的国际化宏命令在哪儿呢?

  类似Objective-C中的NSLocalizedString,你可以在Swift中使用

  NSLocalizedString(key:tableName:bundle:value:comment:)方法为国际化做准备。tableName,bundle以及value arguments都有默认值,所以如果你正使用NSLocalizedString,你可以编写如下代码:

  dispatch_async(dispatch_get_global_queque(DISPATCH_QUEQUE_PRIORITY_BACKGROUND,0),{

  println("test")});


 

 

Swift如何和Grand Central Dispatch一起使用?

  答案:同样的方法,你可以像在Objective-C中那样使用C API。在处理并发性时,你也可以使用苹果高级NSOperationQueue。


 

 

在Swift中有id的等价替代吗?

  答案:有。像上边提到的那样,当Objective-C API返回id类型时,Swift使用AnyObject替换。

  AnyObjective类型可以代表任何类类型的实例。另外也有Any可代表任何类型的实例(除了函数类型)。


 

 

对于字典(dictionary)也是一样吗?字典也是强类型(strongly typed)的吗?

  答案:是的,不过你依然可以用AnyObject来解决。对于字典来说,它里边所有的值不是同一个类型也讲得通。以下是用字典表示的从服务器端返回的一个JSON响应:

  来看一个服务器JSON响应的例子,用字典来表示:

  var employee:Dictionary<String,AnyObject>=["FirstName":"Larry","LastName":"Rodgers","Salary":65_000.00]

  这个字典有两个String类型的键和一个Double值类型的键。虽然这是可行的,但可能的话你应该创建一级类模型对象来表示数据,而不是依赖字典。


 

 那么,数组只能包含一个类型的对象吗?如果我想要不同的类型呢?

  答案:在Swift中,强烈建议你使用只包含一种类型的强类型数组,语法像是:

  var goodArray:String[]=["foo","bar"]

  也就是说,从技术上讲,你依然可以创建包含多个类型对象的数组。但最好在做之前问问自己为什么想这么做。按照这种说法,你可以使用AnyObject:创建一个包含不同类型对象的Swift数组:

  var brokenArry:AnyObject[]=["foo",1,12.23,true]


 

 

你能用Swift来调用自己的Objective-C代码或者第三方库吗?如果能,要怎么做呢?

  答案:可以!当你往Xcode项目里添加第一个.swift文件时,系统会提示你让Xcode创建一个桥接头文件(bridging header file)。你可以在这个头文件中导入你希望可见于Swift代码的Objective-C头文件。然后,所有的类无需导入都可为Swift使用,你可以使用和系统类相同的Swift语法来使用自定义Objective-C文件。


 

 

你如何运行REPL?

  答案:在终端运行以下命令,告诉它使用Xcode 6的命令行工具。

  sudo xcode-select-s/Applications/Xcode6-Beta.app/Contents/Developer/然后运行以下代码开始Swift REPL。

  xcrun swift

  如果准备退出,你可以键入:exit或者:quit。你也可以使用CTRL+D快捷键。


 

 

怎样在Playgrounds中看到那些很酷的值的图形?

  答案:你可以在Playgrounds里绘出值的结果,这对于可视化算法是很方便的。在playground里面输入能够产生值的代码:

  for x in 1..10{

  x

  }

  在侧边栏,你会看到类似于“9times”的东西。把鼠标移到这一行上,会出现“+”按钮。点击这个按钮(并确保你打开了Assistant Editor),你将会看到图形。


 

 

Playground中,println()结果在哪里?

  答案:控制台输出。


 

 

有没有Swift不能用的API?

  答案:没有


 

 

有没有Swift可以实现,但Objective-C不能实现的事情?或者反过来说。

  答案:是的。Swift是一门现代语言,引入了很多Objective-C不支持的内容。比如命名空间(namspacing),可选类型(optionals),元组(tuples),泛型(generics),类型推断(type inference)以及其他等等。当然,Objective-C也有一些Swift不具备的特性,比如messaging nil。


 

 

playground是什么?

  答案:playground是一个文件,你可以编写代码的同时即可看到运行效果。对于学习Swift或者新的API,原型代码或者算法真的很有用处!


 

 

 Swift语言是取代Objective-C,还是对其的补充?

  答案:引用苹果官方的一句话,''Objective-C不会消失,Swfit和Objective-C可同时用于Cocoa和Cocoa Touch开发。''因此,你让然可以继续使用Objective-C。然而,苹果似乎鼓励你使用Swift进行新的开发,而不是希望你重写所有的Objective-C代码。我们猜测苹果在未来的框架和API开发中将会逐渐减少使用Objective-C语言,甚至有一天会弃用Objective-C,所以造作准备吧!


 

 

Swift语言适用于其他版本的iOS和OS X系统么?

  答案:适合


 

 

iOS 8和OS X Yosemite的应用程序只使用Swift语言么?

  答案:不是。


 

 

我是个刚入行的开发者,我应该学习Objcetive-C还是Swift,还是两个都学?

  答案:两种都学;理解OC的库和示例项目。


 

 

我有多年的Objective-C开发经验。对于Swift,我是新手么?

  答案:是,但也不是。如果你为苹果平台开发过一段时间,你仍有很大的优势。因为你很熟悉Xocde和Cocoa/Cocoa Touch API。学习Xocde和上千个Cocoa/Cocoa Touch API要比学Swift花的时间更长,所以你有很好的开发基础。长话短说,一旦你熟悉了Swift代码。你就能很快地学习Swift。