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.timeIntervalSinceReferenceDatenil对象
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)/2letmyPath=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:
方法。
定义一个继承自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的选择器是方法的一个引用。在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交互全部内容,希望文章能够帮你解决Swift与Objective-C API交互所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)