【问题标题】:Is there ever a need for a class to override +alloc in Objective-C?在 Objective-C 中是否需要一个类来覆盖 +alloc?
【发布时间】:2009-09-03 04:06:36
【问题描述】:

根据对this question 的一些回答,+alloc 似乎做了一些幕后魔术来为 Objective-C 中的对象实例分配内存。是否需要覆盖 +alloc?

【问题讨论】:

  • 肯所说的。但是......要强调......这样做非常罕见。

标签: objective-c memory-management


【解决方案1】:

这非常罕见。

NSString 是一个重写 +alloc 作为实现细节的类的示例。如果你检查一下,你会发现 +[NSString alloc] 返回了 NSPlaceholderString 类的东西。这是字符串class cluster的部分实现。

您也可以覆盖以从不同的分配 NSZone 分配为默认值。或者,您可以玩一些技巧,例如调用 NSAllocateObject 并为 extraBytes 提供非零值,以在您的 ivars 之后提供动态空间量。例如,您可能认为通常最终得到的 NSString 的私有子类看起来像这样:

@interface {
    NSUInteger length;
    unichar *data;
}

但事实并非如此。它是一个包含长度和字符数据的内存块。不同的 NSString 实例是不同大小的内存块。这是您可以通过直接调用 NSAllocateObject 来安排的事情。

但所有这些都是技巧和技巧。如果你覆盖 +alloc,就会发生一些特别的事情。

【讨论】:

    【解决方案2】:

    +alloc 没有做任何魔法,它只是在 Objective-C 运行时中调用一个方法来获取类实例的大小并分配该内存量。在编写真正的单例时,您可能希望覆盖 +alloc(即,您希望保证只能分配您的类的单个实例)。尽管在编写单例类时很少需要用到这些长度,但您可以。通常,您会覆盖+alloc 以提供替代(例如不在不同区域分配内存,分配与接收类不同的类——这是类集群可能会做的)行为,或者您可以调用+[super alloc] 来执行标准工作,然后添加您自己的自定义。

    【讨论】:

      【解决方案3】:

      我为 Singleton 类覆盖 alloc,例如:

      #import "Singleton.h"
      
      static Singleton * instance;
      
      @implementation Singleton
      
      + (void)initialize
      {
          if (!instance) {
              instance = [[super allocWithZone:NULL] init];
          }
      }
      
      + (id)allocWithZone:(NSZone * const)notUsed
      {
          return instance;
      }
      
      @end
      

      【讨论】:

      • 这通常不是正确的方法,因为您会误导写[Singleton new] 的用户他们不会获得新实例。事实上,该实例获得了两次init-ed 而不是一次。相反,您应该只公开一个 +(instancetype)sharedInstance;class 方法。保护allocWithZone: 不会保护您免受用户使用运行时函数实例化多个实例的影响。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      相关资源
      最近更新 更多