浅谈Swift和Objective-C之间的那点事。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GAVIN_2015/article/details/51236817

Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用。Swift 结合了 C 和 Objective-C 的优点并且不受C兼容性的限制。Swift 采用安全的编程模式并添加了很多新特性,这将使编程更简单,更灵活,也更有趣。Swift 是基于成熟而且倍受喜爱得 Cocoa 和 Cocoa Touch 框架,他的降临将重新定义软件开发。

Swift 的开发从很久之前就开始了。为了给 Swift 打好基础,苹果公司改进了编译器,调试器和框架结构。我们使用自动引用计数(Automatic Reference Counting, ARC)来简化内存管理。我们在 Foundation 和 Cocoa的基础上构建框架栈并将其标准化。Objective-C 本身支持块、集合语法和模块,所以框架可以轻松支持现代编程语言技术。正是得益于这些基础工作,我们现在才能发布这样一个用于未来苹果软件开发的新语言。

Objective-C 开发者对 Swift 并不会感到陌生。它采用了 Objective-C 的命名参数以及动态对象模型,可以无缝对接到现有的 Cocoa 框架,并且可以兼容 Objective-C 代码。在此基础之上,Swift 还有许多新特性并且支持过程式编程和面向对象编程。

swfit和OC间的 联系

  1. swift句尾不需要分号 ,除非你想在一行中写三行代码就加分号隔开。

  2. swift不要写main函数 ,程序默认从上往下执行

  3. swift不分.h和.m文件 ,一个类只有.swift一个文件

  4. swift不在有地址的概念

  5. swift数据类型都会自动判断 , 只区分变量var 和常量let

  6. 强制转换格式反过来了 OC强转:(int)a Swift强转:int(a)

  7. 整数的数据类型可以通过 .min和.max获得最大和最小值

  8. 定义类型的别名语法改变
    OC:typedef int MyInt
    Swift:typealias MyInt = int

  9. swift的模除取余运算符支持小数了 。 如 5%1.5 = 0.5

  10. 关于BOOL类型更加严格 ,Swift不再是OC的非0就是真,而是true才是真false才是假

  11. 与第10点相联系的就是, swift的赋值运算符没有返回值 。防止误用“=”和“==”

  12. swift可以多对多赋值 。 let(x,y) = (1,2)

  13. swift的 循环语句中必须加{} 就算只有一行代码也必须要加

  14. swift的switch语句后面以前只能跟整数, 现在可以跟各种数据类型了 ,如浮点字符串都行,并且里面不用写break,如果不想要没break的效果 即后面的都想执行 那就写上关键字 fallthrough(注意:在fallthrough后面就不能再定义常量变量了)

1、初始化UIView的子类
在iOS应用上实现UI就需要子类化UIView,也就是要重写UIView的init方法。注意:两种语言有所区别。
Objective-C只需在UIView子类中重写必要的init方法。要初始化一个UIView框架,就要重写initWithFrame:框架,如下所示:

@implementation SubUIView
- (id) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self != nil) {
        // ...
    }
    return self;
}
@end

然而Swift需要多一些步骤来重写同一个init方法。首先,重写使用CGRect框架作为其参数的init方法。根据UIView文档,用Swift语言构建时,须重写init( coder: ),但我们不需要这种方法,就用如下代码处理。类属性初始化所需的代码可以在init( frame: )中执行。

class SubUIView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        // ...
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

2、初始化UIViewController的子类
子类化UIViewController是iOS开发的重要步骤。使用Interface Builder的开发者需要重写initWithNibName:bundle:,但既然我们用代码来构建UI,就不需要执行这一方法了。只需重写init方法,在其中初始化类属性即可。

@implementation SubUIViewController
- (id) init
{
    self = [super init];
    if (self != nil) {
        // ...
    }
    return self;
}
@end

Swift也一样要重写init()方法。实现指定的初始化init(nibName:bundle: )来子类化UIViewController。重申:此过程不适用Interface Builder,所以无需定义nibName和bundle的值,而是调用比指定初始化更简单的convenience初始化,将指定初始化init(nibName:bundle: )设为零。现在调用init()来初始化类,用重写的(nibName:bundle: )执行类属性。

class SubUIViewController: UIViewController {
    convenience init() {
        self.init(nibName: nil, bundle: nil)
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // Initialize properties of class
    }  
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
//现在可以创建和调用UIViewController的子类
let viewController: SubUIViewController = SubUIViewController()
self.navigationController?.pushViewController(viewController, animated: false)

3、使用Auto Layout来实现View
没有Interface Builder的情况下,就用Auto Layout中的NSLayoutConstraint类来设置View的大小和位置——注意Objective-C和Swift在这里有微妙差别。

Objective-C使用NSLayoutConstraint类中的constraintWithItem方法。

+ (instancetype)constraintWithItem:(id)view1
                         attribute:(NSLayoutAttribute)attr1
                         relatedBy:(NSLayoutRelation)relation
                            toItem:(id)view2
                         attribute:(NSLayoutAttribute)attr2
                        multiplier:(CGFloat)multiplier
                          constant:(CGFloat)c

Swift使用同一个类中的init方法。

convenience init(item view1: AnyObject,
       attribute attr1: NSLayoutAttribute,
       relatedBy relation: NSLayoutRelation,
          toItem view2: AnyObject?,
       attribute attr2: NSLayoutAttribute,
      multiplier multiplier: CGFloat,
        constant c: CGFloat)

如果是Objective-C,则执行以下代码。这段代码将创建NSLayoutConstraint(定义self.profileImageView和self之间的位置),然后添加到self上。

[self addConstraint:[NSLayoutConstraint constraintWithItem:self.profileImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:kMessageCellLeftMargin]];

使用Swift也可以创建NSLayoutConstraint:

self.addConstraint(NSLayoutConstraint.init(item: self.profileImageView!, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: kMessageCellLeftMargin))

4、选择器
使用UIButton、NSNotificationCenter、NSTimer等时,使用选择器来分配要执行的方法。在Objective-C中,@selector指令代表使用选择器。

- (void)test
{
    // ...
    mTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerCallback:) userInfo:nil repeats:YES];
}

- (void)timerCallback:(NSTimer *)timer
{
    // ...
}

Swift中,不需要使用指令或字符串来分配方法。

func test() {
    // ...
    self.mTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerCallback:", userInfo: nil, repeats: true)
    // ...
}

func timerCallback(timer: NSTimer) {
    // ...
}

5、字符串
尽管在Swift代码中也可以用Objective-C专门处理字符串的NSString,但要使用以String对象为属性的UITextField上的文本或其他的话,就要清楚NSString和String的区别。

在Objective-C中,UITextField上的文本为NSString,所以属性的长度就是字符串的长度。

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    NSString *message = [textField text];
    if ([message length] > 0) {
        // ...
    }

    return YES;
}

Swift是没有长度属性的,所以要用characters属性的count属性。

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let message: String = textField.text!
    if message.characters.count > 0 {
        // ...
    }

    return true
}

在Objective-C中,我们用stringWithFormat:来创建一个格式化字符串。

[self.typingLabel setText:[NSString stringWithFormat:@"%d Typing something cool....", count]];

在Swift中,String里没有stringWithFormat方法,所以用init(format:_ arguments: )代之。我们可以分配一个与NSString格式化结构相同的格式化字符串来创建一个新字符串,然后给arguments赋以相关的值;

self.typingLabel?.text = String.init(format: "%d Typing something cool...", count)

6、从数据类型得到最小&最大值
从数字格式上得到最小和最大值而言,Objective-C和Swift也有差别。Objective-C使用一个预定义宏来得到最小和最大值,但Swift则可以直接从数据类型上得到这些值。Objective-C使用的是如下的宏:

CGFLOAT_MAX
CGFLOAT_MIN
INT32_MAX
INT32_MIN
LLONG_MAX
LLONG_MIN

而Swift则从数据类型上得到最小和最大值

CGFloat.max
CGFloat.min
Int32.max
Int32.min
Int64.max
Int64.min

7、字典和枚举值
Objective-C用NSDictionary来定义NSAttributedString的属性。Swift则用Dictionary而不是NSDictionary,但想为Dictionary分配枚举值的时候,做法稍有不同。

Objective-C直接为NSDictionary分配键值,如下所示:称为NSUnderlineStyleSingle的枚举值不能作为NSDictionary值直接分配,所以要先用@()将它转换成一个对象。

NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};

Swift可以直接为Dictionary分配键值(如下所示)。如果该值定义为AnyObject,那么Swift就跟Objective-C一样不能直接使用枚举值,而是使用rawValue属性代之。

let underlineAttribute: [String: AnyObject] = [NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue]

8、swift独有的范围运算符

a...b 表示 [a,b]  如3...5  就是范围取345

a..<b 表示[a,b)  如35 就是取范围34

可以直接写在 for-in 循环中,或者if判断中 如  for x in 0...5 {}

9 、swift独有的溢出运算符
当你往一个整型常量或变量赋于一个它不能承载的大数时,Swift不会让你这么干的,它会报错。这样,在操作过大或过小的数的时候就很安全了。

var potentialOverflow = Int16.max
// potentialOverflow 等于 32767, 这是 Int16 能承载的最大整数
potentialOverflow += 1
//  出错了
//当然,你有意在溢出时对有效位进行截断,你可采用溢出运算,而非错误处理。Swfit为整型计算提供了5个&符号开头的溢出运算符。
//    &+,&-,&*,&/,&%
var willOverflow = UInt8.max
// willOverflow 等于UInt8的最大整数 255
willOverflow = willOverflow &+ 1
// 这时候 willOverflow 等于 0

10 、 swift独有的元组类型
var point = (x:15,y:20.2)

就是元组名是 point ,里面有两个元素x和y。 有点类似于结构体但是不是

想取出里面的x的值赋值就是 point.x = 30 或者point.0 = 30 (注:元组里面的许多元素可以看作有数组的下标)

可以省略内部元素的名称 var point = (15,20.2) 但是这样的话,想取出值就只能用point.0 = 30 这一种方法了,因为人家没有元素名了好吧。

也可以明确指定元组内每一个元素的类型,假如那个20.2我不想要double类型 我想要是float类型。可以 var point = (Int,String) = (15,20.2)

注意:元组名称和类型不能共存 ,比如你指定类型了 后面就不可以再指定名称了 var point = (Int,String) = (x:15,y:20.2)

如果你想打印的话就写println(point) 打印出来就是(10,20.2)

并且在初始化的时候也可以用下划线省略不需要的元素 如 var point = (_ ,20.2);

11、在switch语句中使用元组类型时还可以用类似SQL语句的语法 添加过滤条件

switch point{

  case let(x,y) where x== y:

      println("x与y的值相等");



}

12、函数的外部参数名

  • 函数原来的格式是这样(箭头后面是返回值) func Sum (num1:Int,num2:Int) –>Int{}

  • 调用时是 Sum(20,20)

  • 加外部参数名的话在方法调用时可读性更好,是写在原参数名的前面, 调用时也必须书写

  • 即 func Sum(numone num1:Int,numtwo num2:Int) –>Int{}

  • 调用时写 Sum(numone:20,numbertwo:20)

  • 如果觉得这样有点麻烦,可以让外部参数名和内部参数名一样

  • 就是 func Sum (#num1:Int,#num2:Int) –>Int{}

  • 调用时写 Sum(num1:20,num2:20)

13、函数的默认参数值

func addStudent (name:string,age:Int = 20) –>string{}

设置了默认的年龄为20 所以再调用时只需要写个名字

addStudent(“ZTE”)

要注意的是,使用了默认参数值, 系统会自动生成一个外部参数名。

想改名字也就要写外部参数名了 即 addStudent(“ZTE”,age:18)

14、函数的输入输出参数

在函数声明时就用inout代替var 这样以后可以在函数内部修改外面的值 类似于C语言的传入指针

func change (inout num:Int) {
  num = 10
}
var a = 20
change(&a)

得到的结果就是10

(注意:写了输入输出参数就不能再用默认函数值的语法了)

用输入输出参数,实现多个返回值功能

func SumAndMinus(num1:Int,num2:Int,inout sum:Int,inout minus:Int){
  sum = num1 + num2
  minus = num1 - num2
}
var sum = 0 ,minus =0
SumAndMinus(20,5,∑,−)

PS:谷歌酝酿将苹果Swift作为安卓APP主要开发语言

安卓操作系统的软件开发语言是Java,而在过去几年中,有关Java的版权,谷歌(微博)和甲骨文之间发生了长期的诉讼。最新外媒消息称,谷歌正在考虑将苹果开发的Swift作为未来安卓软件开发的“一级”语言,此外Facebook、Uber等公司也开始越来越重视Swift的使用。

据美国科技新闻网站TheNextWeb引述知情人士报道,此前苹果Swift转变为开放源码语言,而谷歌、Facebook、和Uber三家公司的代表曾经在英国伦敦开会,专门讨论Swift语言,谷歌决定逐步在安卓系统中采用这种语言。

Java目前是安卓开发最为重要的语言。消息人士表示,至少在最初阶段,Swift语言不会取代Java的重要地位。目前谷歌和甲骨文之间有关Java的诉讼仍在持续中,引发了外界隐忧,消息人士称,谷歌认为Swift和Java相比有着广泛的优势。

Swift目前是一种开源语言,这意味着谷歌可以将其应用到安卓软件开发中,同时不改变安卓的开源移动架构。

点击此处查看英文原文:http://thenextweb.com/dd/2016/04/07/google-facebook-uber-swift/

没有更多推荐了,返回首页