• 1057阅读
  • 2回复

FROM OBJECTIVE-C TO SWIFT: THOUGHTS AND HINTS [复制链接]

上一主题 下一主题
离线aiiaji
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2014-10-17

在这篇文章里我想跟大家谈谈有关我近来从Objective-C过渡到Swift的一些感受。我会尽可能的给大家一些意见,提示一些误区并比较一下在两种语言之间的差异。话不多说,让我们开门见山。

注意:本文讨论的开发环境为Xcode 6 beta 2版本。

单一文件结构 VS 接口-实现

最值得一提的一大改动便是在Objective-C中“[接口].h/[实现].m”这种文件结构被取缔了。

其实我本人是很支持这种文件结构的,因为通过接口文件来获取及共享类特性的方式相当安全而且简单,不过现在不得不面对它不复存在的现实了。

在Swift中并不存在接口与实现分割成两个文件的现象,我们仅需要依靠实现来构建一个类就行了(并且在写的时候甚至不可能添加关于可访问性的修改)。

如果对于这一改动感到无法忍受的话应注意以下事项:

最为明显的:靠直觉。

我们可以借助漂亮的文档来提高类的可读性。举个例子,我们可以把所有想作为public的要素全部挪到文件开头去,也可以采用扩展来区分public和private。

另一个很实用的办法就是在private的方法和变量命名前加一个下划线’_’作为前缀。

下面是混合了以上两种方案的示例:

// Public

extension DataReader {

      

    var data { }

    func readData(){

        var data = _webserviceInteraction()

    }

}

  

// Private implementation

class DataReader: NSObject {

    

    let _wsURL = NSURL(string: "http://theurl.com")

      

    func _webserviceInteraction()->String{

        // ...

    }

}

虽然我们没办法修改类中各元素的可见性,不过我们可以试着让某些访问变得“困难一些”。

一个特殊的方法就是使用嵌套类来把private部分隐藏起来(至少是自动的隐藏),下面是例子:

import UIKit

  

class DataReader: NSObject {

      

    // Public ***********************

    var data:String?{

        get{return private.internalData}

    }

      

    init(){

        private = DataReaderPrivate()

    }

  

    func publicFunction(){

        private.privateFunc()

    }

  

      

    // Private **********************

    var private:DataReaderPrivate

      

    class DataReaderPrivate {

        var internalData:String?

          

        init(){

            internalData = "Private data!"

        }

          

        func privateFunc (){}

    }

}

我们将private的实现放入一个private常量的实例中,然后用“正常”的类的实现来充当接口。不过private部分并非会真正的隐藏起来,只不过在访问的时候需要加上一个private关键字了:

let reader = DataReader()

reader.private.privateFunc()

问题来了:仅是为了最后要将这些private的部分隐藏起来要把代码写得这样怪异值得吗?

我的建议是在可见性的修改出来之前(苹果正在忙这个事),我们还是采用详细的文档或者多少用一点扩展来完成这个事。

常量和变量

在写Objective-C的时候我会很少的使用到const关键字,甚至于我知道有的数据时不会变的(好吧不要吐槽我)。然而在Swift中苹果建议开发者们多花点心思在使用常量(let)而不是变量(var)上。所以请注意要弄明白你的变量的具体要做什么。你会使用常量的频繁度将是你从未想象过的。

委托模式

经过多年的Objective-C和Cocoa代码编写我想大部分人都对使用委托模式养成了一种嗜好。注意了!我们还是可以继续保留这种嗜好的,下面是一个非常简单的例子:

@objc protocol DataReaderDelegate{

    @optional func DataWillRead()

    func DataDidRead()

}

  

class DataReader: NSObject {

    

    var delegate:DataReaderDelegate?

    var data:NSData?

  

    func buildData(){

          

        delegate?.DataWillRead?() // Optional method check

        data = _createData()

        delegate?.DataDidRead()       // Required method check

    }

}

这里我们使用了一个简单的@optional来替换了使用respondToSelector检测委托方法是否存在。

delegate?.DataWillRead?()

请注意我们在协议之前必须加@obj前缀,因为后面使用了@optional。同时编译器也会在这里报一个警告的消息以防你没有加上@obj。

要实现协议的话,我们需要构建一个类来实现它然后用曾经在OC上用过的方式来指派。

class ViewController: UIViewController, DataReaderDelegate {

                              

    override func viewDidLoad() {

        super.viewDidLoad()

          

        let reader = DataReader()

        reader.delegate = self

    }

  

    func DataWillRead() {...}

      

    func DataDidRead() {...}

}

目标-动作模式

另一常用的设计模式:目标-动作模式。我们仍然同样可以像在OC中使用它那样在Swift中实现它。

class ViewController: UIViewController {

          @IBOutlet var button:UIButton

          override func viewDidLoad() {

        super.viewDidLoad()          

        button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)    }

      func buttonPressed(sender:UIButton){...}

}

总结

我不得不承认我偶尔会在编译器报错的时候无能为力的看着它心想:WTF。

我在Swift耗费的实验和测试的次数越多我就会越清晰的明白其价值所在。在我们能舒坦的使用它之前脱离OC去接触Swift开发和训练需要相当大的兴趣的。

来源:thinkandbuild:http://www.thinkandbuild.it/from-objective-c-to-swift/

离线啊冲

只看该作者 沙发  发表于: 2014-10-17

感谢分享
善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线1975335896

只看该作者 板凳  发表于: 2014-10-18

快速回复
限100 字节
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
 
上一个 下一个