【问题标题】:Using a custom allocator in an iOS library在 iOS 库中使用自定义分配器
【发布时间】:2011-11-16 14:59:57
【问题描述】:

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    我现在无法找到证据,但肯定是CFAllocatormalloc_zone_tNSZone 都是免费桥接的。因此,您可以将分配器转换为 NSZone 并传递它。

    我认为您将面临的问题是在 NextStep 添加 NSZone 以允许程序维护多个堆,感觉是它允许程序员在内存中保持相关对象彼此靠近——这有利于缓存——并且在某些情况下丢弃整个对象图而不遍历图,这显然很快。然而,前者在实践中几乎没有什么好处,而后者更容易产生问题而不是真正的好处。因此,Apple 已经从 NSZones 开始退缩,逐渐将相关的运行时调用变为无操作,并删除了详细的文档。 Apple 的感觉是,在 Objective-C 级别,您不应该只维护一个堆(从您的角度来看这是一个次要问题),而且他们总是最清楚如何维护它。

    编辑:另一种想法是替换 NSObject 的 alloc,这是创建内存的东西。 Objective-C 运行时定义得足够好,我们确切地知道alloc 表现出的行为,因此香草版本可能是:

    + (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,然后直接在 [NSObject class] 上使用 class_getClassMethodclass_getMethodImplementationmethod_setImplementation 进行切换它到位。请参阅Object-C Runtime Reference 了解有关这些内容的文档。

    【讨论】:

    • 感谢您的快速回复。我只是尝试将我的 CFAllocator 类型转换为 NSZone 并调用 allocWithZone 而不是 alloc。我的对象已正确分配,但未调用我的分配。我想这是由于你提到的后退:allocWithZone 没有针对我正在使用的对象类型正确实现?
    • 是的,我猜是的。如果类型不兼容,您预计会崩溃,如果它们兼容,您预计会使用分配器,因此可能只是忽略该参数。作为替代方案,您可以尝试替换 NSObject 的 alloc(或者如果您愿意,也可以替换任何其他对象)——我已经更新了我的帖子。我想你可能也想看看dealloc
    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多