Swift和Objective-C可以进行互操作,也就是说可以在Objective-C项目中使用Swift代码,反过来也可以。当然,这种互操作之间最重要的是可以在Swift中调用Objective-C的接口,毕竟目前绝大部分接口都是通过Objective-C提供的。

初始化

在Swift中实例化一个Objective-C的类时,可以用Swift语法调用它的一个初始化器。Objective-C的初始化方法被分割成关键字。例如“initWith”变成“init”,而剩下的部分作为方法的参数名。

Objective-C的代码:

UITableView*myTableView=[[UITableViewalloc]initWithFrame:CGRectZerostyle:UITableViewStyleGrouped];

对应的Swift代码为:

letmyTableView:UITableView=UITableView(frame:CGRectZero,style:.Grouped)

在Swift中不需要调用alloc方法,它会自动处理对象的创建功能。注意:Swift不会显式的调用init方法。

定义变量或者常量的时候,可以省略它的类型,Swift会自动识别。

letmyTextField=UITextField(frame:CGRect(0.0,0.0,200.0,40.0))

为了方便起见,Objective-C的工厂方法被映射为Swift中的初始化器。例如:

UIColor*color=[UIColorcolorWithRed:0.5green:0.0blue:0.5alpha:1.0];

转换为Swift:

letcolor=UIColor(red:0.5,green:0.0,blue:0.5,alpha:1.0)

属性访问

在Objective-C和Swift中访问属性都是使用点操作符。

myTextField.textColor=UIColor.darkGrayColor()
myTextField.text="Helloworld"ifmyTextField.editing{
myTextField.editing=false}

访问和设置属性的时候不需要使用圆括号,上面darkGrayColor之所以有括号,是因为调用的是UIColor的类方法,而不是属性。

Objective-C中不需要参数并且有一个返回值的方法,可以被当作隐含的获取方法(getter),从而使用点操作符。但是在Swift中点操作符只能访问Objective-C中使用@property定义的属性。

方法调用

在Swift中使用点操作符调用Objective-C中的方法。

Objective-C的方法在Swift中调用的时候,它的第一部分成为Swift的基本方法出现在括号之前。然后函数的第一个参数没有名字,剩下的部分作为Swift函数对应的参数名称。
Objective-C语法:

[myTableViewinsertSubview:mySubviewatIndex:2];

Swift代码:

myTableView.insertSubview(mySubviewatIndex:2)

调用无参的方法:

myTableView.layoutIfNeeded()

兼容id类型

Swift包含一个叫AnyObject的协议,与Objective-C中的id类似,可以表示任意类型的对象。AnyObject协议允许你在利用无类型对象的灵活性的同时保持类型安全。
你可以给AnyObject类型的变量赋任意的值:

varmyObject:AnyObject=NSData()

可以直接方法AnyObject类型对象的任意属性和方法,而不需要进行强制类型转换。

letdateDescription=myObject.descriptionlettimeSinceNow=myObject.timeIntervalSinceNow

由于AnyObject类型的变量的类型需要到运行时才能确定,因此可能会导致不安全的代码。特别是你可以访问一个不存在的属性或者方法,它只是在运行时报错。

myObject.characteratIndex(5)
//crash,myObjectdoesn'trespondtothatmethod

在进行类型转换的时候,不一定转换成功,因此Swift返回的是一个Optional值。你可以检查是否转换成功。

letuserDefaults=NSUserDefaults.standardUserDefaults()letlastRefreshDate:AnyObject?=userDefault.objectForKey("LastRefreshDate")ifletdate=lastRefreshDateas?NSDate{
println("\(date.timeIntervalSinceReferenceDate)")
}

如果你能够确定对象的类型,并且不为nil,可以使用as操作符进行强制转换。

letmyDate=lastRefreshDateasNSDatelettimeInterval=myDate.timeIntervalSinceReferenceDate

nil对象

Objective-C中使用nil来表示引用一个空对象(null)。Swift中所有的值都不会为nil。如果需要表示一个缺失的值,可以使用Optional。

由于Objective-C不能确保所有值都非空,因此Swift将Objective-C中引入的方法的参数和返回值都用Optional表示。在使用Objective-C对象之前,应该检查它们是否存在。

扩展

Swift的扩展与Objective-C的类别有点类似。扩展能够为已有类、结构体、枚举等增加行为。

下面是给UIBezierPath添加扩展:

extensionUIBezierPath{classfuncbezierPathWithTriangle(length:Float,origin:CGPoint)->UIBezierPath{letsquareRoot=Float(sqrt(3))letaltitude=(squareRoot*length)/2
letmyPath=UIBezierPath()

myPath.movetoPoint(orgin)
myPath.addLinetoPoint(CGPoint(length,origin.x))
myPath.addLinetoPoint(CGPoint(length/2,altitude))
myPath.closePath()

returnmyPath
}
}

可以使用扩展增加属性(包括类属性或静态属性)。不过这些属性只能是通过计算得来,而不能进行存储。下面给CGRect添加一个area属性:

extensionCGRect{
vararea:CGFloat{
returnwidth*height
}
}

letrect=CGRect(x:0.0,y:0.0,width:10.0,height:50.0)
letarea=rect.area
//area:CGFloat=500.0

使用扩展可以在不创建子类的情况下让现有的类响应某个协议。需要注意的是,扩展不能覆盖已有的方法和属性。

闭包

Objective-C中的Block 被自动导入为Swift的闭包。例如:

void(^completionBlock)(NSData*,NSError*)=^(NSData*data,NSError*error){/*...*/}

在Swift 中对应为:

letcompletionBlock:(NSData,NSError)->void={
data,errorin/*...*/}

Swift的闭包和Objective-C中的Block是兼容的,可以在Swift中给Objective-C的方法传递闭包来代替Block对象。

闭包和Block对象有一点不同,里面的变量是可变的,也就是说与__block修饰的变量行为相同。

对象比较

Swift中有两种对象比较的方式。第一种是相等(==(equality),用来比较两个对象的内容是否相同。第二种是恒等(===(identity),比较两个变量或者常量是否引用同一个对象。

NSObject只能比较是否引用了同一个对象(恒等),如果要比较内容是否相同,应该实现isEqual:方法。

Swift类型兼容性

定义一个继承自NSObject或者其他Objective-C的类,它自动与Objective-C兼容。如果你不需要将Swift对象导入Objective-C代码的话,没必要关注类型的兼容性。但是如果在Swift中定义的类不是Objective-C类的子类,在Objective-C中使用的时候,需要用@objc进行说明。

@objc使得Swift的API可以在Objective-C和它的运行时中使用。当使用@IBOutlet@IBAction或者@NSManaged等属性时,自动添加@objc属性。

@objc还可以用来指定Swift中的属性或方法在Objective-C中的名字,比如Swift支持Unicode名字,包括使用中文等Objective-C不兼容的字符。还有给Swift中定义的函数指定一个Selectorde名字。

@objc(Squirrel)class长沙戴维营教育{
@objc(hideNuts:inTree:)
func欢迎光临(Int,姓名:String){/*...*/
}
}

@objc(<#name#>)属性作用在Swift的类上时,这个类在Objective-C的使用不受命名空间的限制。同样,在Swift中解归档Objective-C归档的对象时,由于归档对象中存放有类名,因此需要在Swift中用@objc<#name>说明Objective-C的类名。

Objective-C选择器(Selector)

Objective-C的选择器是方法的一个引用。在Swift中对应的是Selector结构体。使用字符串字面量可以构建一个选择器对象,如let mySelector: Selector = "tappedButton:"。由于字符串字面常量可以自动转换为选择器对象,因此可以在任何需要传递选择器的地方使用字符串字面常量。

importUIKitclassMyViewController:UIViewController{letmyButton=UIButton(frame:CGRect(x:0,y:0,width:100,height:50))

init(nibNamenibNameOrNil:String!,bundlenibBundleOrNil:NSBundle!)
{
super.init(nibName:nibName,bundle:nibBundle)
myButton.targetForAction("tappedButton:",withSender:self)
}

functappedButton(sender:UIButton!){
println("tappedbutton")
}
}

提示
performSelector:以及相关的调用选择器的方法没有被引入到Swfit中来,因为它们不是完全安全的。

如果Swift类继承自Objective-C的类,则它里面的方法和属性都能够作为Objective-C的选择器使用。而如果不是Objective-C的子类,需要使用@objc属性修饰,这个在前面的Swift类型兼容性中有描述。

Swift与Objective-C API交互的更多相关文章

  1. ios – 异常断点处于活动状态时,应用程序在启动时崩溃

    我刚开始继续开发一款适用于商店的传统iPad应用程序.我注意到项目中的异常断点未启用.当我启用它时,应用程序在启动时崩溃,但在输出窗口中没有给出任何信息,而在线程视图中只有相当无用的信息(见下文)我试着解决它..>将Autolayout设置为关闭.>通过编辑和重新保存故事板文件..但到目前为止没有运气.我的猜测是,故事板中的某些内容被破坏了,因为AppDelegates“确实完成了启动……”

  2. ios – 如何使用Objective C类中的多个参数调用Swift函数?

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

  3. ios – Swift 4添加手势:覆盖vs @objc

    我想在我的视图中添加一个手势,如下所示:但是,在Swift4中,我的编译器给出了以下错误:建议添加@objc以将此实例方法公开给Objective-C.实现此目的的另一个选项将覆盖touchesBegan()函数并使用它来处理点击.我试图以“Swift”的方式做到这一点,而不必带入Obj-C.有没有纯粹的Swift方式来添加这个轻击手势而不使用@objc?

  4. ios – 将视频分享到Facebook

    我正在编写一个简单的测试应用程序,用于将视频从iOS上传到Facebook.由于FacebookSDK的所有文档都在Objective-C中,因此我发现很难在线找到有关如何使用Swift执行此操作的示例/教程.到目前为止我有这个在我的UI上放置一个共享按钮,但它看起来已禁用,从我读到的这是因为没有内容设置,但我看不出这是怎么可能的.我的getVideoURL()函数返回一个NSURL,它肯定包含视

  5. ios – Objective-C中“and”关键字的含义是什么?

    我在Xcode中输入了一条评论,但忘了领先//.我注意到了这一点并且突出显示为关键字.我做了一些谷歌搜索,但我似乎无法弄清楚它做了什么.这是什么意思?解决方法它是&&的同义词.见iso646.h.

  6. ios – 以编程方式在Swift中添加联系人

    我想在Swift中以编程方式添加联系人.我发现了一些Objective-C示例,但我没有让它们工作,甚至在Objective-C中也没有.我不希望这涉及到AddressBookUI,因为我想从我自己的UI中获取值.解决方法这是在Swift中添加联系人的快速方法.我在我的iPhone5iOS7.1上验证了它,因为我发现模拟器并不总是与我的手机对AB的东西相同.您可以添加一个按钮并指向此方法:顺便说一下–它假设你已经分配了一个地址簿var,你可以通过覆盖viewDidAppear来打开视图.它也会执行安全提示

  7. ios – Objective-C中的Google用户serverAuthCode nil

    我正在尝试将GoogleSignIn框架集成到iOS应用程序中,并对服务器上的用户进行身份验证.我设法登录用户,但在–(void)signIn:(GIDSignIn*)signIndidSignInForUser:(GIDGoogleUser*)用户withError:(NSError*)错误委托方法,user.serverAuthCode为nil,我需要通过此服务器身份验证代码,嗯,验证服务器上

  8. ios – 为目标c中的方法传递未知类型的参数,可能吗?

    是否可以将未知类型的参数传递给objective-C方法?在C#中你可以写实现这一点,但我知道Objective-C没有泛型,所以有没有其他方法可以在Objective-C中实现这一点?我需要这个,因为我想创建一个方法来改变不同对象的文本颜色,如UITextField和UIButton的占位符文本.所以我的计划是创建一个名为textWhite的方法,然后在此方法中检查对象的类型,然后运行匹配的代码以使文本颜色变为白色.解决方法是的,可以传递未知类型的参数.见下面的例子.请参考使用id对象的链接作为参数Us

  9. ios – Swift指针算术和解除引用;将一些类似C的地图代码转换为Swift

    我有一点似乎没有工作的Swift代码……解决方法您正在指定locationPointer指向新位置,但仍在下一行中使用ptr,并且ptr的值尚未更改.将您的最后一行更改为:或者你可以改变指向var的指针并推进它:

  10. ios – Objective-C和Class Cluster模式

    我已经阅读了有关类集群模式的一些信息,并且接下来会理解:>publicclusterclass只提供没有实际实现的接口,其他类为不同的情况实现它;>它与抽象工厂模式有一些相似之处:当我们调用方法classNameWith时…公共集群类的方法:[[NSNumberalloc]initWithDouble:1.0],因为在调用alloc之后它已经分配了NSNumber的实例,而不是它的子类.那么,有人可以解释实际上如何工作公共集群类的alloc-init方法,以及具体的子类实例化和返回时?

随机推荐

  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,所以编译器会报错,现在来一一解决。

返回
顶部