Objective-c EVER中的对象是否在不经过alloc的情况下创建?

时间:2010-04-18 16:11:23

标签: iphone objective-c

我知道objective-c运行时中有一些函数允许您直接创建对象,例如class_createInstance。我想知道的是,除了根类(NSObject)alloc方法之外,还有什么实际使用这些函数。我认为像KVC绑定这样的东西可能,但是那些不存在于iPhone OS上(据我所知,如果我错了就纠正我),那么有什么可以做到的吗?

如果您想知道/它很重要,我希望通过在类上声明没有ivars但是重写+ alloc方法并调用class_createInstance来以绕开objc运行时的方式分配实例的大小( self,numberofbytesofmyivars)。

由于

EDIT 我想我需要更具体一点。我在运行时向运行时添加类,并可能卸载并重新加载同一类的更改版本。到目前为止,由于像class_addMethod这样的问题,我已经解决了大部分问题,但是在注册类之后,没有相应的ivars。我可以想到的两个解决方案就运行时而言没有实际的ivars,但是重写alloc以确保我通过extraBytes有足够的空间,或者声明一个指向我所有实际ivars的指针的ivar ,然后我可以做任何我想做的事情。我更喜欢使用前一种策略,但有很多事情可能会出错,比如有些东西在不经过我重载的alloc方法的情况下分配了我的对象的实例。有谁知道这些事情之一?

4 个答案:

答案 0 :(得分:1)

我不确定你是否试图改变现有类的行为,这是不安全的,或者试图为你拥有的自定义类做一些事情,这些类是NSObject的直接子类,可能是。

您在实践中看到的几乎所有NSStrings都是私有子类的实例,并且该子类为与该对象内联的字符串分配空间。就像,不是包含指向char *的指针,而是字符数据紧跟在对象中的ivars之后。 NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)中的extraBytes参数用于此目的。

所以一方面,是的,你可以这样做。另一方面,你需要知道你正在使用你的这些东西。如果您尝试使用NSString的私有子类(这是私有的,那么您只是通过运行时内省进行交互),那么您可能会发生冲突。

有一些公共可可类也可以做这样的事情,所以如果你的类直接从NSObject继承,你最好。 NSLock就是其中之一。内存中NSLock自定义子类的布局看起来像{ isa, <ivars of NSLock> <ivars of subclass of NSLock> <more NSLock stuff, space reserved using the extraBytes parameter> }

另外,只是为了它,请注意+ alloc调用+ allocWithZone:和+ allocWithZone:是更常见的覆盖点。

答案 1 :(得分:0)

我不确定你为什么要做你所建议的事情 - 我没有看到你无法这样做的任何理由,但根据{{3} },通常没有理由直接使用class_createInstance(我不知道具体使用它的任何东西)。 class_createInstance也未考虑alloc使用的内存区域或其他可能的优化。如果你只是想隐藏你的ivars,那就有this post

编辑:我认为你正在寻找class_addIvar函数,它(顾名思义)动态地将一个ivar添加到一个类中。它只适用于新的运行时,因此它不能在模拟器上运行,但它可以在iPhone上运行。

编辑2:为了完全清楚(如果还没有),你绝对可以依赖allocWithZone永远被调用。基本Cocoa类(例如NSStringNSArray)会覆盖allocWithZone。几乎从不使用class_createInstance,除了在运行时级别,因此您不必担心Cocoa的任何部分在您的类上使用它。所以原始问题的答案是“不”(或者更具体地说,有时候会创建没有alloc的对象,但不是没有allocWithZone,至少据我所知)。

答案 2 :(得分:-1)

从技术上讲,没有什么可以阻止你覆盖alloc。只需在类中创建一个名为+ alloc的方法。我无法想象你为什么需要这么做。

答案 3 :(得分:-1)

听起来你正在努力管理记忆。让OS在您创建对象时动态分配内存。如果您使用太多,操作系统将发送通知您接近极限。那时你可以解除你不再需要的东西了。

如果您需要大量内存而必须使用技巧,那么您的实现可能需要在核心级别重新思考,而不是试图将您的方形设计融入iPhone OS的圆孔中。

根据您提供的信息,我的意见。