从 C++ 到 Objective-C:STL 和 Cocoa

从 C++ 到 Objective-C:STL 和 Cocoa,第1张

概述C++ 标准库是其强大的一个原因。即使它还有一些不足,但是已经能够算作是比较完备的了。这并不是语言的一部分,而是属于一种扩展,其他语言也有类似的部分。在 Objective-C 中,你不得不在 Cocoa 里面寻找容器、遍历器或者其他一些真正可以使用的算法。 容器 Cocoa 的容器比 C++ 更加面向对象,它不使用模板实现,只能存放对象。现在可用的容器有: NSArray 和 NSMutable

C++ 标准库是其强大的一个原因。即使它还有一些不足,但是已经能够算作是比较完备的了。这并不是语言的一部分,而是属于一种扩展,其他语言也有类似的部分。在 Objective-C 中,你不得不在 Cocoa 里面寻找容器、遍历器或者其他一些真正可以使用的算法。

容器

Cocoa 的容器比 C++ 更加面向对象,它不使用模板实现,只能存放对象。现在可用的容器有:

NSArray 和 NSMutableArray:有序集合; NSSet 和 NSMutableSet:无序集合; NSDictionary 和 NSMutableDictionary:键值对形式的关联集合; NSHashtable:使用弱引用的散列表(Objective-C 2.0 新增)。

你可能会发现这其中并没有 NSList 或者 NSQueue。事实上,这些容器都可以由 NSArray 实现。

不同于 C++ 的 vector<T>,Objective-C 的 NSArray 真正隐藏了它的内部实现,仅能够使用访问器获取其内容。因此,NSArray 没有义务为内存单元优化其内容。NSArray 的实现有一些妥协,以便 NSArray 能够像数组或者列表一样使用。既然 Objective-C 的容器只能存放指针,单元维护就会比较有效率了。

NSHashtable 等价于 NSSet,但它使用的是弱引用(我们曾在前面的章节中讲到过)。这对于垃圾收集器很有帮助。

遍历器

经典的枚举

纯面向对象的实现让 Objective-C 比 C++ 更容易实现遍历器。NSEnumerator 就是为了这个设计的:

NSArray* array = [NSArray arrayWithObjects:object1,object2,object3, nil];
NSEnumerator* enumerator [array objectEnumerator]
Nsstring* aString = @"foo"
ID anObject [enumerator nextObjectwhile (anObject != ) 
{ 
    [anObject doSomethingWithString:aString    anObject }

容器的 objectEnumerator 方法返回一个遍历器。遍历器可以使用 nextObject 移动自己。这种行为更像 Java 而不是 C++。当遍历器到达容器末尾时,nextObject 返回 nil。下面是最普通的使用遍历器的语法,使用的 C 语言风格的简写:

nil
(])} // 双括号能够防止 gcc 发出警告

快速枚举

Objective-C 2.0 提供了一个使用遍历器的新语法,隐式使用 NSEnumerator(其实和一般的 NSEnumerator 没有什么区别)。它的具体形式是:

* someContainer = ...; 
for(ID object in someContainer) // 每一个对象都是用 ID 类型 ... } 
(* object { // 每一个对象都是 Nsstring ...
// 开发人员需要处理不是 Nsstring* 的情况 
}
函数对象

使用选择器

Objective-C 的选择器很强大,因而大大减少了函数对象的使用。事实上,弱类型允许用户无需关心实际类型就可以发送消息。例如,下面的代码同前面使用遍历器的是等价的:

@H_620_301@]
*aString "foo"
@H_620_301@[array makeObjectsPerformSelector:@selector(doSomethingWithString:)withObject];

在这段代码中,每个对象不一定非得是 Nsstring 类型,并且对象也不需要必须实现了 doSomethingWithString: 方法(这会引发一个异常:selector not recognized)。

IMP 缓存

我们在这里不会详细解释这个问题,但是的确可以获得 C 函数的内存地址。通过仅查找一次函数地址,可以优化同一个选择器的多次调用。这被称为 IMP 缓存,因为 Objective-C 用于方法实现的数据类型就是 IMP。

调用 class_getmethodImplementation() 就可以获得这么一个指针。但是请注意,这是指向实现方法的真实的指针,因此不能有虚调用。它的使用一般在需要很好的时间优化的场合,并且必须非常小心。

算法

STL 中那一大堆通用算法在 Objective-C 中都没有对等的实现。相反,你应该仔细查找下各个容器中有没有你需要的算法。

总结

以上是内存溢出为你收集整理的从 C++ 到 Objective-C:STL 和 Cocoa全部内容,希望文章能够帮你解决从 C++ 到 Objective-C:STL 和 Cocoa所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1060543.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存