当前位置:  开发笔记 > IOS > 正文

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

如何解决《是否可以在Objective-C中将-init方法设为私有?》经验,为你挑选了3个好方法。

我需要-init在Objective-C中隐藏(私有)我的类的方法.

我怎样才能做到这一点?



1> Jano..:

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发布(我猜).



2> lehn0058..:

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

- (instancetype)init NS_UNAVAILABLE;

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


你也可以做+(instancetype)new NS_UNAVAILABLE;
请注意,您仍然可以使用[MyObject new]实例化对象;

3> Chris Hanson..:

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

你可以做的是抛出一个NSInternalInconsistencyExceptionif你的-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方法是访问单例的方法,并将其记录为在标题中获取单例实例的方法.在绝大多数情况下,这应该是你所需要的.


是的,为了让编译器满意.否则,编译器可能会抱怨返回非void返回的方法没有返回.
*"没有真正的重大优势"*.完全不真实.显着的优点是你想要强制**单身模式.如果您允许创建新实例,那么不熟悉API的开发人员可能会使用`alloc`和`init`并且他们的代码功能不正确,因为他们有正确的类,但是错误的实例.这是OO中*encapsulation*原则的本质.您隐藏API中的其他类不应该或访问的内容.你不仅要把所有东西都公之于众,还要期待人类跟踪这一切.
指望开发人员遵循模式并不是一个好主意.最好抛出异常,因此不同团队的开发人员不知道.我的私人概念会更好.
这里的回报真的有必要吗?
推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有