防止在iOS中分配类

时间:2013-08-22 20:18:17

标签: ios objective-c class memory

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

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

我想要实现的是B类只拥有getter,只能由类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)值如何返回A中类方法传递的值? (知道+ alloc,-init和/或其他内存分配方法可能无效,因为用户不能直接创建B类 - B中的自定义initWithValue方法也可能不可用)

我对苹果公司的工程师如何做到这一点感到有点困惑..苹果公司不希望我使用隐藏的方法吗?

谢谢你。

1 个答案:

答案 0 :(得分: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:,以便在进行复制时获得不可变对象。这一切都与我上面描述的相同 - 无论哪种方式,你都是从客户端隐藏创建机制。