c swift_swift-objective-c - CSDN
  • SwiftC和C++混编

    2019-06-22 21:33:59
    对于Swift调用C和C++,通常需要OC做桥接(oc调用c和c++),性能得不到优化。我们今天直接用Swift调用C使性能得到全面的提升。苹果号称和C一样快的Swift的demo我们来粒子。 测试环境: Xcode版本:11.0-beta Swift...

     苹果推出Swift后,很快就受到程序猿的青睐,快速、安全、简洁的开发已经是一个大趋势了。如果在加上C和C++真的是天衣无缝了,完美结合。对于Swift调用C和C++,通常需要OC做桥接(oc调用c和c++),性能得不到优化。我们今天直接用Swift调用C使性能得到全面的提升。苹果号称和C一样快的Swift的demo我们来粒子。

    测试环境:
    Xcode版本:11.0-beta   Swift版本:5.0
    
    • Swift直接调用C

    我们直接进入主题,Swift调用C。先创建一个工程SwiftCDemo,然后创建一个C文件,命名为CModel,.h文件创建以下函数:

     

    #ifndef CModel_h
    #define CModel_h
    
    #include <stdio.h>
    
    void printHellow(void);
    int getRandomInt(void);
    
    #endif /* CModel_h */
    

    在.c文件里实现该函数:

    #include "CModel.h"
    #include <stdlib.h>
    
    void printHellow(void){
        printf("hellow world,I am is C language");
    }
    
    int getRandomInt(void){
        return rand();
    }
    

    我们定义两个c函数(c不是很厉害只能这么简单,会使用就好)。我们现在用Swift调用。

    我们定义一个头文件,也就是对外(swift)的接口。我们创建一个.h文件,命名为CBridging.h。

    #ifdef __cplusplus
    extern "C" {
    #endif
        void printHellow(void);
        int getRandomInt(void);
        
    #ifdef __cplusplus
    }
    #endif

    对于上边的定义如果不是很明白,可以自己在网上查查,有很多讲解,我在这里就不多说啦。在创建的时候会有提示是否创建桥接文件,记得点击是,如果点击了否,那么就要自己创建了,怎么创建呢。推荐一篇文章

    我们需要在桥接文件中导入CBridging.h。然后我们在默认的ViewController.swift里运行。

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            print("\n----------------------------\n\n")
            printHellow();
            let cRandomInt = getRandomInt();
            print("\n")
            print("收到C函数的随机数是:\(cRandomInt)");
        }
    
    
    }
    
    

    打印log日志为:

    ----------------------------
    
    
    hellow world,I am is C languagerecive =16807

    到此,我们已经成功的调用的C语言。对于c++呢我们也是这个方法。

    • Swift调用C++

    swift要调用c++和c是一样的。我们先创建一个c++文件,命名为CPPerson。

    在.hpp里声明一个类:

    #include <iostream>
    
    using namespace std;
    
    class CPPerson {
        string name;
        int age;
        bool isNan;
        
    public:
        
        CPPerson();
        CPPerson(const char * name,int age, bool isNan);
        ~CPPerson();
        
        void printPersonInfo();
        const char* getPersonName();
        
    };
    

    在.cpp里实现这个类。

    
    CPPerson::CPPerson(){
        this->name = "管理员";
        this->age = 20;
        this->isNan = true;
    }
    
    CPPerson::CPPerson(const char * name,int age, bool isNan){
        this->name = name;
        this->age = age;
        this->isNan = isNan;
    }
    
    void CPPerson::printPersonInfo(){
        cout << "i am is" << name << ",my age is "<< age;
        if (isNan) {
            cout << "i am a body";
        }else{
            cout << "i am a girl";
        }
    }
    const char* CPPerson::getPersonName() {
        return name.data();
    }
    
    CPPerson::~CPPerson(){
        cout << "释放资源";
    }
    

    我们在CBridging.h中加上c++接口:

    CPersonModel create();
    CPersonModel createBy(const char* name,int age);
    void printPersonInfo(CPersonModel model);
    const char* getPersonName(CPersonModel model);
    void destoryModel(CPersonModel model);

    记得加上声明:

    typedef void* CPersonModel;
    

    我们需要在.cpp文件里实现这些函数:

    CPersonModel create() {
        return new CPPerson();
    }
    CPersonModel createBy(const char* name,int age){
        return new CPPerson(name,age,true);
    }
    void printPersonInfo(CPersonModel model) {
        CPPerson *p = (CPPerson*)model;
        p->printPersonInfo();
    }
    const char* getPersonName(CPersonModel model){
        CPPerson *p = (CPPerson*)model;
        return p->getPersonName();
    }
    void destoryModel(CPersonModel model){
        CPPerson *p = (CPPerson*)model;
        delete p;
    }
    

    在ViewController.swift调用

    let person = createBy("peter", 14);
    printPersonInfo(person);
    let cName = getPersonName(person);
    let name = String(cString: cName!);
    print("fetch name is:\(name)");
    destoryModel(person);
    • C调用Swift

    swift调用C,那么C也能调用Swift。我们来看看是怎么调用的。

    在桥接文件里声明一个回调函数:

    extern void(^ __nonnull swiftFuncIMP)(int);
    

    在CModel.h文件里初始化

    void(^ __nonnull swiftFuncIMP)(int) = NULL;
    

    在swift里声明一个函数,并赋值给这个回调函数。

    func swiftFunImplement(a:Int32) -> Void {
        print("收到一个c函数的Int值->\(a)");
    }
    

    在写个测试调用的函数。我们就可以直接调用了,说了这么多,相信有点头绪了。

    另外还有点,c++调用swift,这个留下来思考。最后附上demo地址。欢迎指正。

    demo地址。

    展开全文
  • 这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。用以输入/输出的参数指针C和Objective-C并不支持多返回值,所以Cocoa API中常常将指针作为一种在方法间传递额外数据的方式...

    Objective-C和C的API常常会需要用到指针。Swift中的数据类型都原生支持基于指针的Cocoa API,不仅如此,Swift会自动处理部分最常用的将指针作为参数传递的情况。这篇文章中,我们将着眼于在Swift中让C语言指针与变量、数组和字符串共同工作。

    用以输入/输出的参数指针

    C和Objective-C并不支持多返回值,所以Cocoa API中常常将指针作为一种在方法间传递额外数据的方式。Swift允许指针被当作inout参数使用,所以你可以用符号&将对一个变量的引用作为指针参数传递。举例来说:UIColor中的getRed(_:green:blue:alpha:)方法需要四个CGFloat*指针来接收颜色的组成信息,我们使用&来将这些组成信息捕获为本地变量:

    var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
    color.getRed(&r, green: &g, blue: &b, alpha: &a)

    另一种常见的情况是Cocoa中NSError的习惯用法。许多方法会使用一个NSError**参数来储存可能的错误的信息。举例来说:我们用NSFileManagercontentOfDirectoryAtPath(_:error:)方法来将目录下的内容列表,并将潜在的错误指向一个NSError?变量:

    var maybeError: NSError?
    if let contents = NSFileManager.defaultManager()
        .contentsOfDirectoryAtPath("/usr/bin", error: &maybeError) {
        // Work with the directory contents
    } else if let error = maybeError {
        // Handle the error
    }

    为了安全性,Swift要求被使用&传递的变量已经初始化。因为无法确定这个方法会不会在写入数据前尝试从指针中读取数据。

    作为数组使用的参数指针

    在C语言中,数组和指针的联系十分紧密,而Swift允许数组能够作为指针使用,从而与基于数组的C语言API协同工作更加简单。一个固定的数组可以使用一个常量指针直接传递,一个变化的数组可以用&运算符将一个非常量指针传递。就和输入/输出参数指针一样。举例来说:我们可以用Accelerate框架中的vDSP_vadd方法让两个数组ab相加,并将结果写入第三个数组result

    import Accelerate
    
    let a: [Float] = [1, 2, 3, 4]
    let b: [Float] = [0.5, 0.25, 0.125, 0.0625]
    var result: [Float] = [0, 0, 0, 0]
    
    vDSP_vadd(a, 1, b, 1, &result, 1, 4)
    
    // result now contains [1.5, 2.25, 3.125, 4.0625]

    用作字符串参数的指针

    C语言中用cont char*指针来作为传递字符串的基本方式。Swift中的String可以被当作一个无限长度UTF-8编码的const char*指针来传递给方法。举例来说:我们可以直接传递一个字符串给一个标准C和POSIX库方法

    puts("Hello from libc")
    let fd = open("/tmp/scratch.txt", O_WRONLY|O_CREAT, 0o666)
    
    if fd < 0 {
        perror("could not open /tmp/scratch.txt")
    } else {
        let text = "Hello World"
        write(fd, text, strlen(text))
        close(fd)
    }

    指针参数转换的安全性

    Swift很努力地使与C语言指针的交互更加便利,因为它们广泛地存在于Cocoa之中,同时保持一定的安全性。然而,相比你的其他Swift代码与C语言的指针交互具有潜在的不安全性,所以务必要小心使用。其中特别要注意:

    • 如果被调用者为了在其返回值之后再次使用而保存了C指针的数据,那么这些转换使用起来并不安全。转换后的指针仅在调用期间保证有效。甚至你将同样的变量、数组或字符串作为多指针参数再次传递,你每次都会收到一个不同的指针。这个异常将全局或静态地储存为变量。你可以安全地将这段地址当作永久唯一的指针使用。例如:作为一个KVO上下文参数使用的时候。

    • 当指针类型为ArrayString时,溢出检查不是强制进行的。 基于C语言的API无法增加数组和字符串大小,所以在你将其传递到基于C语言的API之前,你必须确保数组或字符的大小正确。

    如果你需要使用基于指针的API时没有遵守以上指导,或是你重写了接受指针参数的Cocoa方法,于是你可以在Swift中直接用不安全的指针来使用未经处理的内存。在未来的文章中我们将着眼于更加高级的情况。

    展开全文
  • 一、Swift和Objective-C的联系 Swift和Objective-C共用一套运行时环境,Swift的类型可以桥接到Objective-C(下面我简称OC),反之亦然。两者可以互相引用混合编程。其次就是,OC之前积累的很多类库,在Swift中大...

    一、Swift和Objective-C的联系

    Swift和Objective-C共用一套运行时环境,Swift的类型可以桥接到Objective-C(下面我简称OC),反之亦然。两者可以互相引用混合编程。其次就是,OC之前积累的很多类库,在Swift中大部分依然可以直接使用,当然,Swift3之后,一些语法改变了很多,不过还是有迹可循的。OC出现过的绝大多数概念,比如引用计数、ARC、属性、协议、接口、初始化、扩展类、命名参数、匿名函数等,在Swift中继续有效(可能最多换个术语)。Swift大多数概念与OC一样。当然Swift也多出了一些新兴概念,这些在OC中是没有的,比如范型、元组等。

     

    但是:现阶段Swift 到底能不能取代 Objective-C?

    答案是还不行。

    其实到现在为止 Swift 离完全替代 Objective-C 还是很遥远,因为 Apple 内部一直在用 Objective-C 来做一些 Framework 的开发,底层也不可能用 Swift 实现,所以现在更多的替代是体现在外部开发。

    二、Swift比Objective-C有什么优势?

     

    1、Swift容易阅读,语法和文件结构简易化。

    2、Swift更易于维护,文件分离后结构更清晰。

    3、Swift更加安全,它是类型安全的语言。

    4、Swift代码更少,简洁的语法,可以省去大量冗余代码

    5、Swift速度更快,运算性能更高。

    三、Swift目前存在的缺点

     

    1、版本不稳定,之前升级Swift3大动刀,苦了好多人,swift4目前还未知

    2、使用人数比例偏低,目前还是OC的天下

    3、社区的开源项目偏少,毕竟OC独大好多年,很多优秀的类库都不支持Swift,不过这种状况正在改变,现在有好多优秀的Swift的开源类库了

    4、公司使用的比例不高,很多公司以稳为主,还是在使用OC开发,很少一些在进行混合开发,更少一些是纯Swift开发。

    5、偶尔开发中遇到的一些问题,很难查找到相关资料,这是一个弊端。

    6、纯Swift的运行时和OC有本质区别,一些OC中运行时的强大功能,在纯Swift中变无效了。

    7、对于不支持Swift的一些第三方类库,如果非得使用,只能混合编程,利用桥接文件实现。

    四、Swift其他功能说明

     

    1、Swift的内存管理

    Swift使用自动引用计数(ARC)来简化内存管理,与OC一致。

    2、Swift的可选项类型(Optionals)介绍

    Swift引入了可选项类型,用于处理变量值不存在的情况。Optionals类似于OC中指向nil的指针,但是适用于所有数据类型,而非仅仅局限于类,Optionals相比于OC中的nil指针,更加安全和简明,并且也是Swift诸多最强大功能的核心。

    3、Swift中的 !和  ?

    这两个符号是用来标记这个变量的值是否可选,!表示可选变量必须保证转换能够成功,否则报错,但定义的变量可以直接使用;?表示可选变量即使转换不成功也不会报错,变量值为nil,如果转换成功,要使用该变量时,后面需要加!进行修饰。

    4、Swift中范型的简单说明

    范型是用来使代码能安全工作,swift中的范型可以在函数数据和普通数据类型中使用,例如类、结构体或枚举。范型可以解决代码复用的问题

    //举个简单例子:这两个方法很类似,主要就一个参数类型的区别。
    
          func isIntEqual(x:Int,y:Int) -> Bool {
             return x == y
          }
          func isStringEqual(x:String,y:String) -> Bool {
            return x == y
    
          }
    
     //我们可以利用范型合并一下:
    
      func isObjEqual<T:Equatable>(x:T,y:T) -> Bool {
            return x == y
        }

    这样,当我们使用时,我们如果将两个不同类型的数进行比较,编译器会马上提醒我们,从而快速避免这种情况。

     

    5、Swift的访问权限变更

    swift新增了两种访问权限,权限更细化。具体查看这里:

    访问权限 由大到小 依次为:open,public,internal(默认),fileprivate,private

     

    6、Swift Foundation框架

    为了方便使用,Swift的基本类型都可以无缝转换到 Foundation 框架中的对应类型。

    因为 Cocoa 框架所接受和返回的基本数据类型都是自身框架内的类型,也就是 Foundation 中所定义的像 NSString,NSNumber,NSArray 等这些东西。而脱离 Cocoa 框架进行 app 开发是不可能的事情。因此我们在使用 Swift 开发 app 时无法避免地需要在 Swift 类型和 Foundation 类型间进行转换。如果需要每次显式地书写转换的话,大概就没人会喜欢用 Swift 了。还好 Swift 与 Foundation 之间的类型转换是可以自动完成的,这使得通过 Swift 使用 Cocoa 时顺畅了很多。

    而且这个转换不仅是自动的,而且是双向的,而且无论何时只要有可能,转换的结果会更倾向于使用 Swift 类型。也就是说,只要你不写明类型是需要 NS 开头的类型的时候,你都会得到一个 Swift 类型。

    所以,Swift中的类型和OC的类型对应关系:

    String - NSString

    Int, Float, Double, Bool 以及其他与数字有关的类型 - NSNumber

    Array - NSArray
    Dictionary - NSDictionary 

    7、Swift便捷的函数式编程

    Swift提供了Map、FlatMap、Filter、Reduce等函数方法,能够大大方便我们对对象处理。

    举例最简单的场景:

    Map:

    var results = [1,3,5,7] let results = values.map ({ (element) -> Int in 
       return element * 2 
    }) 
    //"[2, 6, 10, 14]"

    Filter:

    var values = [1,3,5,7,9] 
    let flattenResults = values.filter{ $0 % 3 == 0} 
    //[3, 9]

    Reduce:

    var values = [1,3,5] 
    let initialResult = 0 
    var reduceResult = values.reduce(initialResult, combine: { (tempResult, element) -> Int in 
    return tempResult + element 
    })
    print(reduceResult) 
    //9 

    五、其他补充

    ========================= swift独有 ==================== 

    1、范围运算符

    a...b 表示 [a,b] 包括a和b 。 (如3...5  就是范围取3,4,5)

    a..<b 表示 [a,b) 包括a,不包括b 。 (如3...5  就是范围取3,4)

    常见的如for循环:for i in 0...9{}

     

    2、独有的元组类型

    元组(tuples)把多个值组合成一个复合值。元组内的值可以使任意类型,并不要求是相同类型。eg:

    var value = (Int,String) = (x:15,y:"abc")

    3、swift中使用let定义常量,var定义变量

    使用常量,更加安全,不能够被修改,在需要对对象进行修改的时候 只能用var修饰.

     

    4、if let 、 guard let 的用法

    缩减代码量,安全处理数据逻辑。

     

    ========================= 细节使用区别 ====================

    1、swift不分.h和.m文件 ,一个类只有.swift一个文件,所以整体的文件数量比起OC有一定减少。

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

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

    4、强制类型转换格式不同   OC强转:(int)a      Swift强转:Int(a)

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

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

    7、swift的switch语句后面可以跟各种数据类型了 ,如Int、字符串都行,并且里面不用写break(OC好像不能字符串)

    8、swift  if后的括号可以省略:  if a>b {},而OC里 if后面必须写括号。

    9、swift打印  用print("")    打印变量时可以  print("\(value)"),不用像OC那样记很多%@,d%等。

    10、Swift3的【Any】可以代表任何类型的值,无论是类、枚举、结构体还是任何其他Swift类型,这个对应OC中的【id】类型。

     

     

     六、Swift的前景

    可能很多人会问,到底该不该学Swift,难度大不大?

    我的理解是:

    如果时间可以,可以试着学习,最好能试着写一点代码,单纯的看书或看教程没太大意义,实践出真知。

    其实最初期的学习,更多的是语法的转变而已,这里的难点是不大的,而Swift的思想我们可以后期慢慢学习并深入体会。

     

    最后,我还是希望Swift发展的越来越好,功能和社区完善的更棒

    展开全文
  • Objective-C的语法比较复杂,学习成本非常高,其复杂主要体现在它的类的创建、函数的实现和其他的高级特性上。 Swift是2013年苹果发布的一种新的iOS开发语言,其目的在于替代复杂的Objective-CSwift的设计借鉴了...

    Objective-C的语法比较复杂,学习成本非常高,其复杂主要体现在它的类的创建、函数的实现和其他的高级特性上

    Swift是2013年苹果发布的一种新的iOS开发语言,其目的在于替代复杂的Objective-C。Swift的设计借鉴了目前比较流行的几种开发语言。例如Python、Ruby等,使得Swift用起来非常简单、快捷它比Objective-C的学习成本更低,对开发者来说也更容易上手。

    展开全文
  • DATE: 2019-3-2: Objective-CSwift的区别
  • Swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,或者有一些第三方使用OC写的,没有swift版本,怎么办?那就使用混...
  • 互用性是让 Swift 和 Objective-C 相接合的一种特性,使你能够在一种语言编写的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,你应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的...
  • 文章可能写得有点晚了,Swift语言已经诞生很久的时间了,现在它已经挤掉了OC很大的市场了,但是,总是存在很多老项目,或者是第三方库还没有完全翻译成Swift,因此,混编还是需要的。虽然现在详解可能有点晚,不过...
  • 假设你现在就是一个iOS程序员,你对Objective-C很熟悉,对iOS开发也很熟悉,然而,苹果公司在iOS 8之后推出了Swift语言。那么,如何才能快速地从Objective-C过渡到Swift呢? 本章我们将重点讲解如何从Objective-C...
  • 自2014年苹果推出新的语言编程 Swift ,就引来众人的热议。有人说 Swift 不过是各个语言的大杂烩,也有人说它是编程语言的集大成之作。 尽管热议不断,但是 Swift 还是凭借自身的魅力迅速杀入 Tioble 排行版前十...
  • 真正从「长远角度」看,学习 Objective-C 还是 Swift 语言其实很不重要。 Swift 刚发布的时候有人说「这下所有人都回到零起点了」,实际上是外行的一个常见的误解。Objective-C / Swift 和 iOS 开发是两个不同的...
  • 其实到现在为止 Swift 离替代 Objective-C 还是很遥远,因为 Apple 内部一直在用 Objective-C 来做一些 Framework 的开发,低层也不可能用 Swift 实现 — Cyan 如果把取代定义为编写底层框架的话, 至少以 Swift 3...
  • 本项目为TensorFlow的C语言接口试验性封装函数库,用于Swift在人工智能深度学习上的应用。
  • iOS开发应该选择Objective-C还是Swift,这里会给出你选择:1.如果你想成为一个iOS开发者,你仍然需要学习Objective-C。2.Objective-CSwift更容易学习。3.一旦你学习了Objective-C,学习Swift就很容易了。
  • Swift调用C代码的方法

    2015-08-09 19:25:32
    本篇纪录的是Swift中调用C代码的方法,我使用的是MAC OS X10.10.4的系统,Xcode7beta版,下面是swift调用C的步骤: 1.新建一个命令行工程,取名为TestSwift01 2.创建Objective-C文件,在项目上鼠标右键,选择New ...
  •  Swift 语言出来后,可能新的项目直接使用Swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,或者有一些第三方使用OC写的,没有swift版本,怎么办?那就...
  • 各位亲爱的iOS与OS X应用程序开发人员,如今正是将编程阵地转移至更为亲民、功能更为全面的Swift的最佳时机。 一般而言,编程语言往往不会轻易消亡,不过由相关厂商大力推动的更新换代举措则不在此列。如果大家...
  • Swift已经推出了一段时间了,今天来总结一下Swift与Objective-c(以下简称OC)的语法有哪些不同。 1.常量与变量: 在Swift中定义常量和变量很简单,常量使用let关键字,变量使用var关键字。 var numberOfRows = 30...
  • 刚开始写Swift,还是有很多不习惯,...所以我就自己写一个iOS的UI系列,对比着Objective-CSwift,希望对像我一样刚入门Swift的小伙伴有所帮助~ Objective-C代码实现UIView: -(void)setupView{ //初始化一个...
  • Object-C调用Swift, 创建Swift文件,然后在需要调用Swift文件的地方加上 #import "工程名-Swift.h" Swift调用 Object-C 创建Swift文件的时候,会出现问是否要创建Bridging-header.h.当然点击Yes。 把你要引用的oc...
1 2 3 4 5 ... 20
收藏数 53,346
精华内容 21,338
关键字:

c swift