我正在创建一个将由多种类型的iOS应用程序使用的库。我的API的一部分允许用户指定将用于库分配的例程。我的库主要是用C ++实现的,所以到目前为止这很简单。
但是,我最近一直在为库添加一些用户界面功能:使用自定义视图控制器显示UIWebView
。我不确定如何确保我的分配器用于这些对象。
如何确保我的库创建的所有Cocoa UI对象都使用我自己的函数进行分配?
我尝试过一些事情,包括覆盖-initWithZone
并在CFAllocatorSetDefault
之前调用-init
。他们都还没有工作;说实话,我仍然是 Objective C 和 Cocoa 的初学者,所以我想知道“正确”的方法是什么。
答案 0 :(得分:4)
我现在无法找到证据,但CFAllocator
,malloc_zone_t
和NSZone
都是免费桥接的。所以你可以将你的分配器转换为NSZone并传递它。
我认为你要面对的问题是在NextStep中添加了NSZone,以便允许程序维护多个堆,感觉是它允许程序员在内存中保持相关对象彼此靠近 - 这对于缓存很有用 - 并且在某些情况下会丢弃整个对象图而不会走图形,这显然很快。然而,前者在实践中几乎没有什么好处,而后者更有可能产生问题而不是实际利益。因此,Apple已经从NSZone
反向兜售,逐渐将相关的运行时调用转换为无操作并删除详细的文档。 Apple的感觉是,在Objective-C级别,您不仅应该只维护一个堆(从您的角度来看这是一个副问题),而且他们总是最了解如何维护它。
编辑:另一个想法是替换NSObject的alloc
,这是创造记忆的东西。 Objective-C运行时已经定义得足够清楚,我们确切地知道了alloc
所展示的行为,因此vanilla版本可能是:
+ (id)alloc
{
Class *newInstance;
// we'll use calloc to ensure we get correct initial behaviour of
// everything equal to 0, and use the runtime's class_getInstanceSize
// so that we're allocating the correct amount of memory irrespective
// of whether this call has fallen through from a subclass
newInstance = (Class *)calloc(1, class_getInstanceSize(self));
// the thing that defines a class is that the first thing stored in
// it is the isa pointer, which points to the metaclass. So we'll
// set the isa pointer appropriately
*newInstance = self;
return (id)newInstance;
}
要替换NSObject的普通init,您可能希望将替代方法定义为NSObject上的类别方法,例如customInit,然后直接使用class_getClassMethod
,class_getMethodImplementation
和method_setImplementation
在[NSObject class]
上将其切换到位。有关这些内容的文档,请参阅Object-C Runtime Reference。