>是否可以将Swifts数值桥接复制到Foundation:s NSNumber引用类型,例如: Int32,UInt32,Int64和UInt64类型?具体来说,复制下面介绍的自动按配置桥接.

此类解决方案的示例用法:

let foo : Int64 = 42
let bar : NSNumber = foo
    /* Currently,as expected,error:
       cannot convert value of type 'Int64' to specified type 'NSNumber */

背景

一些原生的Swift数(值)类型可以自动桥接到NSNumber(引用)类型:

Instances of the Swift numeric structure types,such as Int,UInt,
Float,Double,and Bool,cannot be represented by the
AnyObject type,because AnyObject only represents instances of a
class type. However,when bridging to Foundation is enabled,Swift
numeric values can be assigned to constants and variables of
AnyObject type as bridged instances of the NSNumber class.

Swift automatically bridges certain native number types,such as Int
and Float,to NSNumber. This bridging lets you create an
NSNumber from one of these types:

06001

It also allows you to pass a value of type Int,for example,to an
argument expecting an NSNumber
. …

All of the following types are automatically bridged to NSNumber:

06002

从Interoperability – Working with Cocoa Data Types – Numbers起.

那么为什么要尝试为IntXX / UIntXX类型复制它呢?

主要是:通过最近看到一些问题引发的好奇心,这些问题包括为什么Int值类型看起来可以用AnyObject(引用)变量表示的混淆,而不是Int64,不能;这可以通过上面描述的桥接自然解释.选几个:

> Why is a Swift Array<Int> compatible with AnyObject?
> Cannot subscript a value of type ‘[UInt32]’
> Using generic arrays in swift

然而,上面提到的Q& A:中没有提到从非桥接类型Int64,UInt16等实际实现对AnyObject(NSNumber)的这种自动桥接的可能性.这些线程中的答案非常集中(正确地)解释为什么AnyObject不能保存值类型,以及IntXX / UIntXX类型如何不被桥接以自动转换为前者的基础Foundation类型.

其次:对于在32位和64位体系结构上运行的应用程序,有一些狭窄的用例 – 使用Swift本机数字类型隐式转换为AnyObject,在某些上下文中使用例如Int32或Int64类型优先于Int.一个(有点)这样的例子:

> Why does this random function code crash on an iPhone 5 and 5S.

是(可能):符合协议_ObjectiveCBridgeable

(以下答案基于使用Swift 2.2和XCode 7.3.)

正如我在思考是否发布或只是跳过这个问题一样,我在Swift源代码中偶然发现了swift/stdlib/public/core/BridgeObjectiveC.swift,特别是协议_ObjectiveCBridgeable.我之前在Swiftdoc.org时曾经简要地注意过该协议,但是在后者的当前(空)蓝图中,我从来没有考虑过它.使用来自Swift源的_ObjectiveCBridgeable的蓝图,我们可以迅速让一些自定义类型的本地符合它.

在继续之前,请注意_ObjectiveCBridgeable是一个内部/隐藏协议(_UnderscorePreFixedProtocol),因此在即将推出的Swift版本中,基于它的解决方案可能会在没有警告的情况下中断.

启用Int64桥接到Foundation类NSNumber

作为示例,扩展Int64以符合_ObjectiveCBridgeable,并随后测试这个非常简单的修复是否足以从Int64到Foundation类NSNumber保持的隐式类型转换(桥接).

import Foundation

extension Int64: _ObjectiveCBridgeable {

    public typealias _ObjectiveCType = NSNumber

    public static func _isBridgedToObjectiveC() -> Bool {
        return true
    }

    public static func _getobjectiveCType() -> Any.Type {
        return _ObjectiveCType.self
    }

    public func _bridgetoObjectiveC() -> _ObjectiveCType {
        return NSNumber(longLong: self)
    }

    public static func _forceBridgeFromObjectiveC(source: _ObjectiveCType,inout result: Int64?) {
        result = source.longLongValue
    }

    public static func _conditionallyBridgeFromObjectiveC(source: _ObjectiveCType,inout result: Int64?) -> Bool {
        self._forceBridgeFromObjectiveC(source,result: &result)
        return true
    }
}

测试:

/* Test case: scalar */
let fooInt: Int = 42
let fooInt64: Int64 = 42
var fooAnyObj : AnyObject

fooAnyObj = fooInt    // OK,natively
fooAnyObj = fooInt64  // OK! _ObjectiveCBridgeable conformance successful

/* Test case: array */
let fooIntArr: [Int] = [42,23]
let fooInt64Arr: [Int64] = [42,23]
var fooAnyObjArr : [AnyObject]

fooAnyObjArr = fooIntArr    // OK,natively
fooAnyObjArr = fooInt64Arr  // OK! _ObjectiveCBridgeable conformance successful

因此,与_ObjectiveCBridgeable的一致性确实足以启用自动的分配桥接到相应的Foundation类;在这种情况下,NSNumber(在Swift中,__ NSCFNumber).

启用Int8,UInt8,Int16,UInt16,Int32,(Int64)和UInt64桥接到NSNumber

使用下面的NSNumber转换表,可以很容易地修改Int64到_ObjectiveCBridgeable的上述一致性,以涵盖任何Swift原生整数类型.

/* NSNumber initializer:               NSNumber native Swift type property
   --------------------------------    -----------------------------------
   init(char: <Int8>)                  .charValue
   init(unsignedChar: <UInt8>)         .unsignedCharValue
   init(short: <Int16>)                .shortValue
   init(unsignedShort: <UInt16>)       .unsignedShortValue
   init(int: <Int32>)                  .intValue
   init(unsignedInt: <UInt32>)         .unsignedIntValue
   init(longLong: <Int64>)             .longLongValue
   init(unsignedLongLong: <UInt64>)    .unsignedLongLongValue              */

对于(U)Int8 / 16/32/64类型,是否可以将Swifts自动数值桥接复制到Foundation(NSNumber)?的更多相关文章

  1. ios – UIColor到十六进制(网页颜色)

    有没有简单的方法将UIColor转换为十六进制值?

  2. ios – 如果我将自动释放的对象桥接到Core Foundation,我必须使用__bridge或__bridge_retained吗?

    ARC迁移工具遇到了这个问题:特别是,它不确定它是否应该执行__bridge或__bridge_retained.而我也是.-fileURLWithPath返回一个自动释放的对象,在这个地方我不是fileURL的所有者.但与此同时,该对象的保留计数至少为1.我敢打赌,这只能用__bridge来完成.解决方法您只想为此使用常规__bridge强制转换.仅当您想要管理强制转换CF对象的生命周期时,才会使用__bridge_retained.例如:所以__bridge_retained确实告诉编译器你有一个AR

  3. Swift学习笔记十七——导入Foundation使用更多字符串功能

    在Xcode6.3版本中,默认创建playground项目时会导入一个UIKit包。但是如果没有导入UIKit包,可以通过importFoundation,来使用更多的字符串功能。字符串首字母大写方法:capitalizedString输出结果如下:。但是最初str的值并未改变。删除字符串前缀后缀方法:stringByTrimmingCharactersInSet输出结果:。以上方法都在Foundation下,使对字符串的操作更加灵活方便。

  4. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

  5. Swift 2.0学习笔记Day 1——我的第一行Swift代码

    importFoundationvarstr="HelloWorld"print晕晕、好吧,低头继续往下看,哦明白了第一句:importFoundation表示引入Foundation框架。Foundation是OSX和iOS应用程序开发的基础框架,它包括了一些基本的类,如数字、字符串、数组、字典等。UIKit框架是iOS图形用户界面开发需要框架,包括常见的视图和视图控制器等。

  6. Swift访问Foundation框架

    Foundation框架提供了大量的界面无关的api,为CoreFoundation框架的许多功能提供了Objective-C和Swift的封装。Foundation定义了大量的类,大体可分为值对象集合操作系统服务:文件系统、URL、进程通讯通知归档和序列化-下面的代码,基于Swift,对Foundation常用的api进行了简单的访问。包括结构体NSRange、NSSize、NSPoint,日期NSDate,字符串Nsstring,文件读写,字典操作等。说明写在注释中。

  7. 《从零开始学Swift》学习笔记Day60――Core Foundation框架

    虽然在Swift中调用这种C语言风格的API比较麻烦,但是在OSX和iOS开发过程中,有时候使用CoreFoundation框架的API是非常方便的,例如在与C语言混合编码的时候。CoreFoundation框架与Foundation框架紧密相关,他们具有与相同的接口,但是不同。CoreFoundation框架是基于C语言风格的,而Foundation框架是基于Objective-C语言风格的。看看Swift原生类型与CoreFoundation类型之间的转换示例:这个转换过程中CoreFoundatio

  8. 《从零开始学Swift》学习笔记Day 61――Core Foundation框架之内存管理

    Swift类型内存管理是采用ARC,Foundation类型和CoreFoundation类型内存管理都是采用MRC或ARC,CoreFoundation类型内存管理是基于C语言风格的,它有一个对象所有权的概念Objective-C的MRC内存管理CoreFoundation的内存管理与Objective-C的MRC内存管理密不可分,先介绍一下Objective-C的MRC内存管理。为了保证对象的存在,可以调用retain方法保持对象,retain方法会使其引用计数加1,如果不需要这个对象可以调用rele

  9. 《从零开始学Swift》学习笔记Day 62――Core Foundation框架之内存托管对象与非托管对象

    内存非托管对象内存非托管对象就是内存需要程序员自己管理。这是由于在获得对象的方法中没有使用CF_RETURNS_RETAINED或CF_RETURNS_NOT_RETAINED注释声明,编译器无法帮助管理内存。内存非托管对象使用起来有些麻烦,要根据获得所有权方法,进行相应的处理。调用者不再使用对象时候,Swift代码中需要调用CFRelease函数放弃对象所有权,这是因为Swift是ARC内存管理的。

  10. Swift:Foundation框架中的NS前缀的由来

    可能大家对于著名的NS前缀的由来有一些疑问.绝大多数这些NS前缀的类是NeXTSTEP操作系统中Foundation框架里的一部分,而该操作系统是OSX的基础.NeXTSTEP的程序员对它们的类和函数使用NX前缀.这个前缀在NeXT和Sun合作创建OpenStep之后被改为NS,OpenStep是一个面向对象的框架,它用来在其他平台上提供类似于NeXTSTEP的环境.所以,取决于你向谁提出这个问题,一些人会说NS指的是NeXTSTEP,而另一些人会说NS指的是NeXT/Sun.;]

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部