为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以在Objective-C中将-init方法设为私有?

是否可以在Objective-C中将-init方法设为私有?

POPMUISE 2019-10-24 11:07:19
我需要-init在Objective-C中隐藏(设为私有)我的类的方法。我怎样才能做到这一点?
查看完整描述

3 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

与Smalltalk一样,Objective-C也没有“私有”与“公共”方法的概念。任何消息都可以随时发送到任何对象。


您可以做的是在调用NSInternalInconsistencyException您的-init方法时抛出:


- (id)init {

    [self release];

    @throw [NSException exceptionWithName:NSInternalInconsistencyException

                                   reason:@"-init is not a valid initializer for the class Foo"

                                 userInfo:nil];

    return nil;

}

另一种选择-在实践中可能要好得多-尽可能使-init您的班级做出明智的选择。


如果由于要“确保”使用单例对象而尝试执行此操作,请不要打扰。具体地,不与打扰“覆盖+allocWithZone:,-init,-retain,-release”创建单身的方法。实际上,这几乎是不必要的,只是增加了复杂性而没有真正的明显优势。


相反,只需编写代码,使您的+sharedWhatever方法成为访问单例的方式,并将其记录为在标头中获取单例实例的方式。在绝大多数情况下,这就是您所需要的。


查看完整回答
反对 回复 2019-10-24
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

NS_UNAVAILABLE

- (instancetype)init NS_UNAVAILABLE;

这是不可用属性的简短版本。它首先出现在macOS 10.7和iOS 5中。在NSObjCRuntime.h中将其定义为#define NS_UNAVAILABLE UNAVAILABLE_ATTRIBUTE。


有一个版本仅对Swift客户端禁用此方法,而不对ObjC代码禁用:


- (instancetype)init NS_SWIFT_UNAVAILABLE;

unavailable

将unavailable属性添加到标头,以在每次调用init时生成编译器错误。


-(instancetype) init __attribute__((unavailable("init not available")));  

编译时错误


如果没有理由,请输入__attribute__((unavailable)),甚至__unavailable:


-(instancetype) __unavailable init;  

doesNotRecognizeSelector:

使用doesNotRecognizeSelector:提出一个NSInvalidArgumentException。“只要对象收到无法响应或转发的aSelector消息,运行时系统就会调用此方法。”


- (instancetype) init {

    [self release];

    [super doesNotRecognizeSelector:_cmd];

    return nil;

}

NSAssert

使用NSAssert抛出NSInternalInconsistencyException并显示一条消息:


- (instancetype) init {

    [self release];

    NSAssert(false,@"unavailable, use initWithBlah: instead");

    return nil;

}

raise:format:

使用raise:format:抛出自己的异常:


- (instancetype) init {

    [self release];

    [NSException raise:NSGenericException 

                format:@"Disabled. Use +[[%@ alloc] %@] instead",

                       NSStringFromClass([self class]),

                       NSStringFromSelector(@selector(initWithStateDictionary:))];

    return nil;

}

[self release]因为该对象已经被alloc吃掉而需要。使用ARC时,编译器会为您调用它。无论如何,当您有意停止执行时,不必担心。


objc_designated_initializer

如果您打算禁用init强制使用指定的初始化程序,则可以使用以下属性:


-(instancetype)myOwnInit NS_DESIGNATED_INITIALIZER;

除非myOwnInit内部有其他初始化方法调用,否则将生成警告。下一个Xcode发布后,详细信息将发布在“ 采用现代Objective-C”中(我想)。


查看完整回答
反对 回复 2019-10-24
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

Apple已开始在其头文件中使用以下命令禁用init构造函数:


- (instancetype)init NS_UNAVAILABLE;

这在Xcode中正确显示为编译器错误。具体来说,这是在其几个HealthKit头文件中设置的(HKUnit是其中之一)。


查看完整回答
反对 回复 2019-10-24
  • 3 回答
  • 0 关注
  • 785 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信