1

我想知道如何在 Objective-C 中创建一个无法分配(或初始化)的类?

我正在尝试复制 SKDownload Apple 类(StoreKit 框架),我注意到文档没有提到任何 alloc 或 init 方法。这可能在文档中丢失但出现在代码中?(缺少一些 .h 声明以阻止我们使用此方法?)。我试过 +alloc-init 这个类,alloc 和 init 都返回 null。

我想要实现的是一个只有 getter 的 B 类,它只能由 A 类创建(就像工厂方法一样 - 只有 A 可以创建和返回 B 实例,但用户不能直接创建 B ) .

例子:

@interface A : NSObject
// Only A "+createB" class method can create B instances
+ (Second *)createBWithValue:(int)value;
@end

@interface B : NSObject
- (id)init; // return nil
+ (id)alloc; // return nil
- (int)value; // this returns the value passed from A
@end

问题 1:您将如何继续创建此类课程?有可能吗?

问题2: B上的-(int)value如何返回A中类方法传入的值?(知道 +alloc、-init 和/或其他内存分配方法可能无效,因为用户无法直接创建 B 类 - B 中的自定义 initWithValue 方法也可能不可用)

我对 Apple 工程师如何做到这一点感到有些困惑……是否存在 Apple 不希望我使用的隐藏方法?

谢谢。

4

1 回答 1

2

我注意到文档没有提到任何 alloc 或 init 方法

从文档中:

您的应用从不直接创建 SKDownload 对象。相反,在处理完付款后,您的应用程序会读取交易对象的下载属性以检索与交易关联的 SKDownload 对象数组。

是否有 Apple 不希望我使用的隐藏方法?

是的。Apple 不希望您使用许多隐藏的方法。

所以,这个想法是你不应该创建SKDownload自己的实例,因此初始化方法不是公共 API 的一部分。这并不意味着没有创建SKDownload实例的方法,只是没有公开的方法供创建它们。

类限制分配或初始化是很常见的。例如,单例类通常会覆盖+allocWithZone:,这样它只会在尚未创建新对象时分配一个新对象;如果存在,则返回该对象(并且初始化程序基本上什么都不做)。

隐藏初始化程序。

如果您想自己创建一个这样的类,请覆盖继承的初始化方法(可能只是-init),以便它们返回nil甚​​至可能引发异常。实现您自己的初始化程序,但不要将其置于类的公共接口之外:

// B.h
@interface B : NSObject
@property(readonly) int value;
@end;

// B.m
@interface B ()
@property(readwrite) int value;
-(id)secretInitializerWithValue:(int)v;
@end

@implementation B
-(id)secretInitializerWithValue:(int)v
{
    if ((self == [super init])) {   // not really necessary since NSObject's -init doesn't do anything
        _value = v;
    }
}

-(id)init
{
     @throw [NSException exceptionWithName:@"Don't do that!" 
                                    reason:@"You shouldn't instantiate B yourself."
                                  userInfo:nil];
}
@end

私有可变子类。

另一种选择是创建一个具有所需只读访问器的不可变类,以及一个具有读写访问器的私有可变子类。您可以-copyWithZone:在可变子类中实现,以便在制作副本时获得不可变对象。这与我上面描述的几乎相同——无论哪种方式,您都在向客户端隐藏创建机制。

于 2013-08-22T20:24:13.590 回答