代码之家  ›  专栏  ›  技术社区  ›  wadesworld

objective-c包装器api设计方法

  •  3
  • wadesworld  · 技术社区  · 14 年前

    我知道没有人能回答这个问题,但我想听听人们对如何应对这种情况的看法。

    我正在给一个c库编写一个objective-c包装器。我的目标是:

    1)包装器使用objective-c对象。例如,如果C API定义了一个参数,比如char*name,那么objective-C API应该使用name:(nsstring*)。

    2)使用objective-c包装器的客户机不必了解c库的内部工作原理。

    速度真的不是问题。

    简单的参数很容易做到。接受nsstring并将其转换为c字符串以将其传递给c库当然没有问题。

    当涉及到复杂的结构时,我会犹豫不决。

    假设你有:

    struct flow
    {
        long direction;
        long speed;
        long disruption;
        long start;
        long stop;
    } flow_t;
    
    And then your C API call is:
    
    void setFlows(flow_t inFlows[4]);
    

    所以,有些选择是:
    1)向客户端公开流结构,并让objective-c api获取这些结构的数组
    2)构建包含属性的四个nsdictionary的nsarray,并将其作为参数传递
    3)创建包含结构属性的四个“flow”对象的nsarray,并将其作为参数传递

    我对这些方法的分析:
    方法一:最简单。但是,它没有达到设计目标
    方法二:由于某种原因,在我看来,这是最“客观C”的方式。但是,nsdictionary的每个元素都必须包装在nsnumber中。现在看来,我们做了很多事情来传递一个等价的结构。
    方法3:从面向对象的角度来看,对我来说似乎是最干净的,而且额外的封装稍后可能会派上用场。然而,就像2,现在我们似乎做了很多事情(创建数组、创建和初始化对象)来传递结构。

    所以,问题是,你将如何处理这种情况?还有其他的选择我不考虑吗?我所提出的方法有没有其他的优点或缺点,我没有考虑?

    4 回复  |  直到 14 年前
        1
  •  2
  •   jessecurry    14 年前

    我认为方法3是最好的方法。当你包装一个库的时候,你会想在任何对象或结构周围创建包装器,用户需要处理。

    如果你把所有的东西都包装起来,那么你就可以自由地在以后更改类的内部工作方式,而不影响用户已经习惯的接口。例如,将来您可能会意识到您希望添加某种类型的错误检查或更正…也许是设定一个 stop 那比 start 导致一些计算错误,您可以更改 停止 要设置的流包装器中的方法 开始 等于 停止 如果 停止 小于 开始 (我承认,这是个很糟糕的例子)。

        2
  •  2
  •   greg    14 年前

    我坚持3号进近。你在“传递一个结构” 现在 ,但流对象将来可能会扩展得更多。你说速度不是问题,所以我想内存消耗也不是问题,否则你还是要坚持C。

        3
  •  1
  •   user296139    14 年前

    我的回答不是你所问的,但仍然是我如何“处理这种情况”。

    我要问的第一个问题是,“这个包装器增加了什么值?”如果答案是“使用objective-c语法”,那么答案是“不要改变任何东西,按原样使用库,因为c是objective-c语法。”

    我不知道你在包装哪个库,所以我将使用sqlite作为一个从头开始的例子。使用分层的方法,我会这样做:

    a)高级对象(订单、客户、供应商…)

    b)基类(记录)

    C)SQLite

    所以基类被编写成直接调用sqlite,然后其他类作为常规的objective-c类工作。

    任命如下:

    1)高级对象(订单、客户、供应商…)

    2)基类(记录)

    3)sqlite包装器(objective-c)

    4)SQLite

    创建了同一个应用程序,但是创建、维护和调试级别3需要做额外的工作,几乎没有显示出来。

    在第一个版本中,b层包装了sqlite,所以上面没有直接调用sqlite,也没有试图提供所有的sqlite功能。它只提供了层a所需的功能,并使用sqlite来实现所需的功能。它“包装”了sqlite,但使用了更特定于应用程序的方式。同一个记录类可以稍后在另一个应用程序中重用,并进行扩展以满足两个应用程序当时的需要。

        4
  •  0
  •   Stephen Furlani    14 年前

    既然objective-c使用结构,为什么不把它作为类似于结构的 NSRect ?