V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
WhoCanBeRich
V2EX  ›  问与答

问一下关于 iOS 的问题呀,性能重写方面的

  •  
  •   WhoCanBeRich · 2019-06-30 00:06:32 +08:00 · 1703 次点击
    这是一个创建于 1973 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我今天看 iOS52 个有效方法里有这样一句话:
    "实际上,消息派发并非应用程序的瓶颈所在,假如真实个瓶颈的话,那你可以只编写纯 C 函数,在调用时根据需要,把 Object-C 对象的状态传进去。"
    限于我现在的水平,我能明白它在表达什么意思,但是不知道该怎么用 C 语言重写 OC 的代码,比如我现在最简单有一个 OC 的 Person 类,有一个 speak 方法,我在实例化的时候做了如下的事情:
    Person *personOne = [[Person alloc] init];
    [personOne speak];
    我该怎么样用 C 语言来实现这同样功能呢?
    求牛牛们指导哈
    9 条回复    2019-06-30 16:22:51 +08:00
    kingfun
        1
    kingfun  
       2019-06-30 01:41:19 +08:00
    personOne.speak();
    iyeatse
        2
    iyeatse  
       2019-06-30 03:27:01 +08:00
    没想到现在还有写 OC 的新同学,现在大家都浮躁了,一个两个全去搞 RN、Flutter 了。
    主楼的描述是在说如果嫌动态派发太慢的话需要用 C 改成静态调用吧。
    按照主楼的例子,你要做的事是把 `-[Person speak]` 方法改写成 `void personSpeak(Persion *persion)`,
    然后调用的时候 `personSpeak(persionOne)`
    (或者把 IMP 取出来直接调
    (用 swift 就没这些烂事了
    jaskle
        3
    jaskle  
       2019-06-30 07:13:01 +08:00 via Android
    性能都过剩了,玩什么 c 和 oc,如果来个做 rn 的,几天做了你几个月的活,你的老板会怀疑你的能力。
    WhoCanBeRich
        4
    WhoCanBeRich  
    OP
       2019-06-30 08:53:54 +08:00
    @iyeatse 好的呀 谢谢你!
    WhoCanBeRich
        5
    WhoCanBeRich  
    OP
       2019-06-30 09:46:42 +08:00
    @iyeatse 已经实现了你说的代码了,真的 ok 非常感谢!
    WhoCanBeRich
        6
    WhoCanBeRich  
    OP
       2019-06-30 09:47:37 +08:00
    @iyeatse 为啥用 swift 就没这些事了呢 还能请教一下嘛
    secondwtq
        7
    secondwtq  
       2019-06-30 15:24:53 +08:00 via iPad
    Person 是你软件中的一个组件,所谓类 /方法是编程语言提供给你的实现组件的方式。软件的高层设计其实和具体语言的关系并不大。编程语言会灌输给你各种奇怪的名词概念,比如同一样东西,iOS 叫 protocol,Java 叫 interface (而 ObjC 的 interface 则更像是 C++ 的 class declaration ),虽然细节有区别,但是大体意思是一样的,这就是所谓的不同编程语言间通用的东西。比如你在学 protocol 的用法,其实在了解了基本语法之后,可以顺便看看 Java 的 interface 是怎么用的,Scala 的 trait 是怎么用的。

    所谓的类和方法某种程度上也算是编程语言给你灌进去的东西——虽然严格上来说并不是,但是我觉得一个程序员应该掌握脱离类等概念进行软件设计的能力。iOS 相关的资料自然会鼓励你用他推荐的语言和工具,让你习惯于他自己的那套玩法,所以楼主发现自己需要学习相关知识时,居然是由于“性能”的缘故,而我觉得这方面能力的意义并不仅仅在性能上。

    楼主所提到的这个过程应该属于所谓的 modular design。通俗的说,假设我们现在不是在重写 ObjC 的 Person 类,而是用 C 写一个哈希表。那你会先考虑用什么算法,需要哪些操作,这些操作的接口是怎样的。比如 C 不会给你构造函数或者 init 函数,你得自己实现一个 hash_table_create 函数,还有对应的 hash_table_free 函数,没有类和方法,那你就不能定义 size() 方法,而是定义 hash_table_size 函数。C 不能像 C++ 或者 Python 一样做 [] 运算符的重载,那你得实现一个 hash_table_get 函数,你会发现虽然没有高级语言的工具,程序还是能照常写,这是最基本的要求。

    再深一点你会考虑如果我实现一个红黑树会是什么样的接口,红黑树的接口和哈希表的接口有什么区别,哈希表要不要暴露出 bucket 数目、允许用户自行 rehash 之类的细节,甚至“使用同一个哈希表 /红黑树的实现来实现集合和关联数组两种模块该如何设计”之类的奇怪问题。

    这类入门书建议看 C Interfaces and Implementations (简单了解没必要看书,看看公开的示例代码就行),休闲可以看 A Philosophy of Software Design 之类的

    Swift 具体实现不了解,查了一下,按照 https://allegro.tech/2014/12/swift-method-dispatching.html 这篇文章的说法,Swift 方法调用经过编译器优化后实际是与 C 实现等价的。
    WhoCanBeRich
        8
    WhoCanBeRich  
    OP
       2019-06-30 16:20:53 +08:00
    @secondwtq 非常感谢你那么走心的回答!不知道能加你一个 wx 否? 我目前大四刚就业,BAT 某家...
    WhoCanBeRich
        9
    WhoCanBeRich  
    OP
       2019-06-30 16:22:51 +08:00
    @secondwtq 你推荐的两本书也是非常好!感谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   998 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:49 · PVG 03:49 · LAX 11:49 · JFK 14:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.