Martin

思想空间

我是Martin,iOS / Android 开发者。


欢迎来到我的思想空间

swift 类型转换笔记

swift 类型转换笔记

AnyObject

为了便于理解,你可以认为AnyObject是一种“type”(实际上并不是type),就像Double ,Array等,AnyObject主要用于兼容现有的Objective-C API和iOS代码,swift不能用AnyObject构建自己的数据结构,swift是强类型语言,并有类型推断的特性。

什么是AnyObject?在哪会看到AnyObject?

AnyObject的意思是指向一个对象的指针,也就是一个对象的实例,但你不知道它是什么class,所以它是指向未知类的指针

有时它会是某个类的属性如:

        var destinationViewController: AnyObject
        var toolbarItems: [AnyObject]

也有可能出现在方法的参数中:

        func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject)
        func addConstraints(constraints: [AnyObject])

也可以作为返回值返回:

        class func buttonWithType(buttonType: UIButtonType) -> AnyObject                       

怎么使用AnyObject?

为了使用它,我们把它转换成一种我们知道的类型

我们新建一个我们已知类型的变量,“变量 = AnyObject 转换后的东西“

我们可以使用 as 关键词进行强制转换,例如:

         var destinationViewController: AnyObject
         let calcVC = destinationViewController as CalculatorViewController 如果destinationViewController不是CalculatorViewController或者它的子类,程序将会crash

如果想防止crash,我们可以使用

         if let with as?
         if let calcVC = destinationViewController as? CalculatorViewController {
         ...
         }

as? 返回一个可选类型(如果destinationViewController不是CalculatorViewController类型,calcVC = nil)

也可以在之前判断是不是CalculatorViewController类型:

         if destinationViewController is CalculatorViewController {
         ...
         }

通常我们更多的使用as?

Array中的AnyObject

         vat toolbarItems: [AnyObject]
         for item in toolbarItems {  //item的类型是AnyObject
             if let toolbarItem = item as? UIBatButtonItem {
                 //toolbarItem的类型是UIBatButtonItem
             }
         }

或者

         for toolbarItem in toolbarItems as [UIBarButtonItem] {
             //toolbarItem的类型是UIBatButtonItem
         } 这里不能使用as? 因为toolbarItem不应该为nil,所以在使用这个方法是最好确定toolbarItems的类型是UIBarButtonItem        

关于 as

由上可知,as可以用于将AnyObject转换为其他类型,同时as也可以用于其他任何类型的转换,但是对于两个非AnyObject对象,想要通过as转换,他们必须在同一条继承链上,并且只能向下转换。例如:

         let vc : UIViewController = CalculatorViewController()
         //vc被声明为UIViewController类型,但是创建了一个CalculatorViewController实例对象,这是是不能用vc调用CalculatorViewController的方法的
         if let calcVC = vc as? CalculatorViewController {
             //calcVC可以调用 CalculatorViewController的方法
         }  

Objective-C 兼容性

Bridging

Bridging意思是你可以对他们随意互换

NSString is bridged to String

NSArray is bridged to Array < AnyObjecy>

NSDictionary is breidged to Dictionary < NSObject, AnyObjecy>

Int, Float, Double, Bool are all bridged to NSNumber,在需要传入NSNumber时可以随意使用Int,Float等,但反过来不行,需要使用NSNumber的intValue, floatValued等方法

Int, Float, Double, Bool are all bridged to c语言的 int,float,double,bool

如果需要确定的类型,可以使用as进行转换(不需要使用as?)。例如:

         let length = (aString as NSString).length //length是NSString的方法
         (anArray as NSArray).componentsJoinedByString(NSString) 
         //componentsJoinedByString是NSArray的方法

这里我们可能会对NSDictionary有点疑问,它只接受NSObject作为key,我们知道swift中String,Array等都不是对象,而是结构,但因为他们bridged to NSObject的子类(NSString, NSArray)等,所以它们也是可以作为NSDictionary的key使用的。

总结 as的使用场景

  • 对AnyObject进行转换
  • 将父类对象转换为子类对象
  • 对于具有bridge关系的对象进行相互转换

使用初始化方法实现类型转换

         let d: Double = 37.5
         let f: Float = 37.5
         let x = Int(d)
         let xd = Double(x)
         let cgf = CGFloat(d) 
         
         let a = Array("abc") // a = ["a", "b", "c"]
         let s = String(["a", "b", "c"]) // s = "abc"
         
         let s = String(52) //不能是float
         let s = "\(37.5)" 
         
         var f = 123.32342342
         var s = String(format: "%.2f", f) //123.32,保留2位小数
         
         let i = 255
         let s:String = String(format: "%x", i) //ff, 转换成十六进制
         
         let i = 255
         let s:String = String(format: "%06x", i) //0000ff, 不足六位前面补0
         
         let s = "32.5"
         let d = Double(s)
         let fd = (NumberFormatter().number(from: s)?.doubleValue)!

另外提一下AnyObject和Any的区别

AnyObject只能代表class类型,不能处理纯swift的结构等类型。

Any可以处理结构等所有类型。

参考:ANY 和 ANYOBJECT

最近的文章

iOS开发tips

打log在 Xcode 的 Build Setting 中,在 Other Swift flags 的 Debug 栏中加入 -D DEBUG 即可加入一个编译标识。添加方法:/// 打log方法,release不会输出 ////// - Parameters:/// - message: log 文本/// - fileName: 文件名,有默认值/// - methodName: 方法名,有默认值/// - lineNumber: 行数,有默认值public func ...…

总结知识管理继续阅读
更早的文章

swift 可选值

swift 可选值总结先看几个例子: var optionalStr : String! //声明可选值,默认为nil optionalStr = nil if optionalStr == nil { // 通过条件判断 }当初看到这段代码时,非常奇怪,按照之前浅显的理解,被标记为!的应该必然有值啊,这段代码应该报错才对啊?后面仔细查看文档,...…

总结知识管理继续阅读