当前位置:首页 > 操作系统 > Ios

使用swift语言进行IOS应用开发

         在Swift中能够直接使用Objective-C语言提供的api (包括系统框架与自己的定制代码),也能够在Objective-C中使用Swift提供的类和api ,还能够在一个工程中同时混合使用Swift 和Objective-C两种语言,两种语言之间能够互通和互用。

      任意Objective-C的框架或C库(包括所有的Objective-C系统框架,例如Foundation、UIKit、SpriteKit以及系统提供的公共c库)作为模块被直接导入Swift 供Swift语言使用。

      例如为了使用Foundation框架,只需简单的在要使用Foundation框架的Swift文件的顶部添加一个如下的输入声明语句:

       import Foundation

      这样Foundation 框架包含的所有api包括NSDate、NSURL、NSMutableData以及所有的方法、属性和类别都能被该Swift文件直接使用。

一 、与Objective-C 语言和框架的集成

1.1 对象的实例化

         为了在  Swift 中使用某个Objective-C 类,可以使用Swift语法调用它的某个初始化方法进行实例化。

    UITableView * myTableView = [[ UITableView alloc ] initWithFrame: CGRectZero style: UITableViewStyleGrouped ];

         以上的一个Objective-C 对象的初始化方法在Swift语言中需要这样调用。

    let  myTableView : UITableView = UITableView ( frame : CGRectZero , style : . Grouped )

       由于Swift语言自动处理一个实例的内存分配,因此在Swift语言中不需要使用alloc进行内存分配。Objective-C 语言中作为实例初始化方法名字指示的init或 initWith前缀在Swift的初始化语法中也不需要,而用类的名字作为实例初始化方法的名字,跟着Objective-C 语言实例初始化方法名字initWith后面的单词作为Swift的初始化方法的第一个参数使用。

    在Swift语言中,实例的初始化语法中对象的类型 也可以省掉(如上例的UITableView),Swift可以自动正确地推断其类型,如下所示:

      let  myTableView = UITableView ( frame : CGRectZero , style : . Grouped )

       为了一致和简化,Objective-C 的工厂方法在导入Swift时被自动映射为Swift语言的便利初始化方法。例如在Objective-C中如下调用一个工厂方法。 

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

    在Swift语言中,应该这样调用:

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

1.2 属性和方法的存取

     在Swift中使用点语法来存取和设置Objective-C 对象的属性和调用方法。

     对于属性的存取在Swift中利用点语法直接使用属性的名字来存取该属性,如:

myTextField . textColor = UIColor . darkGrayColor ()

myTextField . text = "Hello world"

    对于方法,Objective-C方法名字的第一部分在Swift中直接作为方法名,其余作为Swift方法的参数包括在方法的圆括号中。例如下面的一个Objective-C 方法。

     [ myTableView insertSubview: mySubview atIndex: 2 ];

     在Swift中如下调用。

     myTableView . insertSubview ( mySubview , atIndex : 2 )

    在Objective-C中的id类型 在导入Swift时被映射为Swift语言的AnyObject类型。

    在Objective-C中的指针在导入Swift时被映射为Swift语言的optional类型。

   1.3 扩展功能

     能够使用扩展为Objective-C语言中已定义的类、结构和枚举(包括系统框架中或自己定义的)添加和扩展功能。

     如使用扩展来添加属性(包括类和静态属性),扩展的属性必须是计算属性。如下所示使用扩展为CGRect类添加了一个计算属性area

extension  CGRect {

    var  area : CGFloat {

    return  width * height

    }

}

let  rect = CGRect ( x : 0.0 , y : 0.0 , width : 10.0 , height : 50.0 )

let  area = rect . area

// area: CGFloat = 500.0

     也能使用扩展来为Objective-C语言的类添加协议的支持,如果协议是Swift定义的,你能为任意的结构或枚举类型(无论是Objective-C定义的还是Swift定义的)添加对该协议的支持。

     但不能使用扩展来重写Objective-C 类型的属性或方法。

1.4   块与闭合

       Objective-C中的块以Swift中的闭合方式导入Swift。

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

   上面 Objective-C语言定义的块在 导入 Swift后需要这样使用(转换为闭合):

   let  completionBlock : ( NSData , NSError ) -> Void = { data , error in /* ... */ }

   由于 Swift中的闭合和 Objective-C中的块是兼容的,因此你能够传递闭合(包括Swift的函数)给任何使用块作为参数的Objective-C方法。

   1.5  对 Objective-C类的继承和使用Objective-C中的协议

               在Swift 语言中,能定义一个继承自一个Objective-C类的Swift 类,也能在Swift 中直接使用Objective-C语言定义的协议。如下定义了一个派生自Objective-C框架 UIKit中UIViewController类的一个 Swift 子类。

import  UIKit

class  MySwiftViewController : UIViewController {

    // define the class

}

         如下定义了一个采用Objective-C中的 UITableViewDelegate和UITableViewDataSource 协议 Swift 类MySwiftViewController。

class  MySwiftViewController : UIViewController , UITableViewDelegate , UITableViewDataSource {

    // define the class

}

                 对于 Swift 定义的类(包括从Objective-C继承的类)总是使用Swift语言的初始化方法进行类的初始化,Swift自动转换Objective-C 的初始化方法为Swift中的初始化方法。 

     1.6 与Objective-C的兼容

                 当定义一个Swift类派生自NSObject或其它的Objective-C类时,Swift类自动与Objective-C兼容,Objective-C代码可以直接使用它。

                 注意在Objective-C中不能定义一个继承Swift类的子类。

                 如果Swift类不派生自Objective-C类,则Objective-C代码不能直接使用它,如果要使该Swift类能够被Objective-C代码使用,需要使用 @objc 来标识它。

                当在 Objective-C代码中使用一个Swift API 时,编译器自动执行一个直接转换操作。Swift 的API 被转换为Objective-C的形式。

                如Swift 中的一个函数func playSong(name: String)被转换为Objective-C语言的如下形式- (void)playSong:(NSString *)name。

                Swift 的一个初始化方法init (songName: String, artist: String)被转换为Objective-C语言的如下形式:

                 - (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist。

               在 Swift中,也能使用@objc对类、属性、方法规定一个能够被Objective-C语言识别和使用的另外的名字。如下所示:

@objc ( Squirrel )

class  Белка {

    @objc ( initWithName :)

    init ( имя : String ) { /*...*/ }

    @objc ( hideNuts : inTree :)

    func  прячьОрехи ( Int , вДереве : Дерево ) { /*...*/ }

}

 1.7、  与Cocoa数据类型的桥接

        Swift能够自动在一些Objective-C 和Swift类型之间相互转换,另外也有一些类型,能够在Swift和Objective-C 之间相互替换使用。可转换或可替换的类型被称作可桥接类型。如Swift 语言中的Array类型和Objective-C 中的NSArray类,Swift 中的String类型与Objective-C 中的NSString类,Swift 的Dictionary类型与Objective-C 中的NSDictionary类,都是可桥接类型。

     在Swift中,使用NSString的任何地方都能用String代替,并能同时使用两种类型提供的功能,如可以在Swift的String类型上调用NSString提供的capitalizedString方法。

  为了在Swift中允许和使用桥功能,只需输入Foundation框架。如下所示:

import  Foundation

let  greeting = "hello, world!"

let  capitalizedGreeting = greeting . capitalizedString

// capitalizedGreeting: String = Hello, World!

         还 能够像创建String一样创建一个NSString对象,如下所示创建了一个 NSString类型的对象

import  Foundation

let  myString : NSString = "123"

if  let  integerValue = ( myString as String ). toInt () {

    println ( " ( myString ) is the integer ( integerValue ) " )

}

         Swift也自动在Int、Float、UInt、Double、Bool类型与NSNumber类型之间实现类型的桥接,因此可以使用Int、Float、UInt、Double、Bool类型来创建一个NSNumber对象。在需要的NSNumber类型参数的地方也可以传送一个Int、Float、UInt、Double、Bool类型的参数。

let  n = 42

let  m : NSNumber = n

            注: Cocoa 的NSNumber类型与NSUInteger类型都被桥接为Swift的Int类型。

        当从一个 NSArray对象桥接为一个Swift Array数组时,NSArray数组的类型需要与AnyObject兼容,结果数组的类型为AnyObject[]。由于所有的Objective-C对象与AnyObject类型兼容,因此任何类型的NSArray对象都能被桥接为Swift数组。

     同样,如果Swift数组中的元素与AnyObject兼容,一个Swift数组也能桥接为NSArray对象,否则将会出运行时错误。

     同样也能像创建一个Swift数组一样创建一个NSArray对象。

let  schoolSupplies : NSArray = [ "Pencil" , "Eraser" , "Notebook" ]

// schoolSupplies is an NSArray object containing NSString objects

二、 与 C API的交互    

 2.1、 C语言基本类型

        Swift提供了与C语言基本类型对等的类型。但除非特别需要,不推荐使用。

C Type                      Swift Type

 bool                              CBool

char , signed char       CChar

unsigned char             CUnsignedChar

short                             CShort

unsigned short             CUnsignedShort

int                                 CInt

unsigned int                 CUnsignedInt

long                               CLong

unsigned long               CUnsignedLong

long long                       CLongLong

unsigned long long     CUnsignedLongLong

wchar_t                           CWideChar

char16_t                         CChar16

char32_t                         CChar32

float                             CFloat

double                           CDouble


2.2   C-style类型的枚举

    在Objective-C 语言中用NS_ENUM宏标记的C-style类型的枚举或用NS_OPTIONS标记的选项在导入Swift时被自动转换为Swift形式的枚举。

OBJECTIVE-C

typedef NS_ENUM( NSInteger , UITableViewCellStyle ) {

  UITableViewCellStyleDefault ,

  UITableViewCellStyleValue1 ,

  UITableViewCellStyleValue2 ,

  UITableViewCellStyleSubtitle

};

被转换为如下的Swift枚举形式。

SWIFT

enum UITableViewCellStyle : Int {

    case Default

    case Value1

    case Value2

    case Subtitle

}

2.3 指针

   Swift避免直接使用指针,可是当需要时也提供了几种类型的指针供直接存取内存使用。

   对于作为参数的指针,有如下映射关系:

C Syntax         Swift Syntax

const void *             CConstVoidPointer

void *                       CMutableVoidPointer

const Type *             CConstPointer<Type>

Type *                         CMutablePointer<Type>

    对于作为返回类型、变量和参数类型的指针,有如下映射关系:

C Syntax          Swift Syntax

void *             COpaquePointer

Type *             UnsafePointer<Type>

    对于类的指针,有如下映射关系:

C Syntax          Swift Syntax

Type * const *           CConstPointer<Type>

Type * __strong *     CMutablePointer<Type>

Type **                           AutoreleasingUnsafePointer<Type>

     以上的Type是一个占位类型,可以代表任意类型。

2.4 宏定义和条件编译

   C语言使用#define定义的基本常量在导入Swift时被Swift编译器自动转换为Swift 语言的全局变量。但复杂的宏定义不能被Swift转换。      

   Swift代码也支持条件编译,如下所示:

#if build configuration && !build configuration

    statements

#elseif build configuration

    statements

#else

    statements

#endif

三、   与Interface Builder集成

      在Swift也是使用@IBOutlet@IBAction来定义Outlets属性和Actions动作,用来实现代码与用户接口对象的连接。如下所示,在MyViewController类中声明了与用户接口对象连接的一个outlet属性、一个outlet属性数组、一个action动作。

class  MyViewController : UIViewController {

    @IBOutlet  var  button : UIButton

    @IBOutlet  var  textFields : UITextField []

    @IBAction  func  buttonTapped ( AnyObject ) {

        println ( "button tapped!" )

    }

}

     当使用@IBOutlet来声明一个outlet时,Swift自动把转换为一个弱引用隐含型的已展开选项类型,并分配它的初始值为nil。

     Swift中使用@IBDesignable属性来声明一个能够在Interface Builder中使用的特定视图对象,使用@IBInspectable属性声明一个可以在Interface Builder中的inspector中进行编辑的视图属性。如下所示声明了一个视图和相关的属性:

@IBDesignable

class  MyCustomView : UIView {

    @IBInspectable  var  textColor : UIColor

    @IBInspectable  var  iconHeight : CGFloat

    /* ... */

}

四、 混合使用Swift与Objective-C语言

     在一个单独的工程中,还能够同时包含Objective-C和Swif文件。

     为了使一组Objective-C文件被相同应用工程中的Swif文件使用,需要使用Xcode创建一个Objective-C桥接头文件,并在桥接头文件中导入每一个被Swift用到的Objective-C头文件。桥接头文件的名字为产品名字加“-Bridging-Header.h”后缀。

      OBJECTIVE-C头文件

#import "XYZCustomCell.h"

#import "XYZCustomView.h"

#import “XYZCustomViewController.h"

    Objective-C桥接头文件中添加的Objective-C头文件中定义的功能将能够自动被相同工程的Swift文件使用。

    Objective-C代码需要使用相同应用工程中的Swift代码时,Xcode自动产生一个包含相同工程中所有Swift文件接口声明的Objective-C 头文件,接口文头件为产品模块名字加“-Swift.h”后缀。

    然后在要使用Swift代码的Objective-C文件中采用如下形式导入该头文件。

     #import “ProductModuleName-Swift.h”

    然后该 Objective-C文件将可使用 相同工程中的所有Swift文件中公开的功能

        为了在一个Objective-C头文件中引用一个Swift类,需要使用@class在引用前面对该类进行声明。如下所示:


OBJECTIVE-C

// MyObjcClass.h

 

@class  MySwiftClass ;

 

@interface  MyObjcClass : NSObject

- ( MySwiftClass *) return SwiftObject ;

/* ... */

          

                                                 

原文:http://blog.csdn.net/goohong/article/details/36176603


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!