在iOS库中使用自定义分配器

时间:2011-11-16 14:59:57

标签: objective-c cocoa-touch memory-management

我正在创建一个将由多种类型的iOS应用程序使用的库。我的API的一部分允许用户指定将用于库分配的例程。我的库主要是用C ++实现的,所以到目前为止这很简单。

但是,我最近一直在为库添加一些用户界面功能:使用自定义视图控制器显示UIWebView。我不确定如何确保我的分配器用于这些对象。

如何确保我的库创建的所有Cocoa UI对象都使用我自己的函数进行分配?

我尝试过一些事情,包括覆盖-initWithZone并在CFAllocatorSetDefault之前调用-init。他们都还没有工作;说实话,我仍然是 Objective C Cocoa 的初学者,所以我想知道“正确”的方法是什么。

1 个答案:

答案 0 :(得分:4)

我现在无法找到证据,但CFAllocatormalloc_zone_tNSZone都是免费桥接的。所以你可以将你的分配器转换为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_getClassMethodclass_getMethodImplementationmethod_setImplementation[NSObject class]上将其切换到位。有关这些内容的文档,请参阅Object-C Runtime Reference