Ant*_*ony 17 objective-c nsobject ios
我想强制用户使用我自己的init方法(例如-(id)initWithString:(NSString*)foo;)而不是基本的[[myObject alloc]init];.
我怎样才能做到这一点?
fzw*_*zwo 20
虽然在某人调用您的方法时很容易在运行时崩溃,但编译时检查会更好.
幸运的是,这在Objective-C中已经有一段时间了.
使用LLVM,您可以将类中的任何方法声明为不可用
- (void)aMethod __attribute__((unavailable("This method is not available")));
Run Code Online (Sandbox Code Playgroud)
这将使编译器在尝试调用时抱怨aMethod.大!
由于- (id)init这只是一种普通的方法,因此您可以禁止以这种方式调用默认(或任何其他)初始化程序.
但请注意,这不能保证使用语言的动态方面调用方法,例如通过[object performSelector:@selector(aMethod)]等.在init的情况下,您甚至不会收到警告,因为init方法在其他方法中定义类,编译器不知道足以给你一个未声明的选择器警告.
因此,为了确保这一点,请确保在调用时init方法崩溃(参见Adam的回答).
如果你想- (id)init在框架中禁止+ (id)new,请确保也禁止,因为这只会转发到init.
Javi Soto编写了一个小宏来禁止使用指定的初始化程序更快更容易并提供更好的消息.你可以在这里找到它.
Cod*_*der 14
TL; 博士
斯威夫特:
private init() {}
Run Code Online (Sandbox Code Playgroud)
由于默认情况下所有Swift类都包含一个内部init,因此您可以将其更改为private以防止其他类调用它.
目标C:
把它放在你班级的.h文件中.
- (instancetype)init NS_UNAVAILABLE;
Run Code Online (Sandbox Code Playgroud)
这依赖于OS定义,该定义阻止调用命名的方法.
接受的答案是错误的 - 你可以做到这一点,这很容易,你只需要有点明确.这是一个例子:
你有一个名为"DontAllowInit"的类,你想阻止人们初始化:
@implementation DontAllowInit
- (id)init
{
if( [self class] == [DontAllowInit class])
{
NSAssert(false, @"You cannot init this class directly. Instead, use a subclass e.g. AcceptableSubclass");
self = nil; // as per @uranusjr's answer, should assign to self before returning
}
else
self = [super init];
return nil;
}
Run Code Online (Sandbox Code Playgroud)
说明:
完美的工作.注意:我不推荐这种技术用于"普通应用",因为通常你INSTEAD想要使用协议.
但是......在编写库时......这种技术非常有价值:你经常想要"保存(其他开发人员)自己",并且很容易让NSAssert告诉他们"哎呀!你试图分配/初始化错误的类!试试X级......".
| 归档时间: |
|
| 查看次数: |
5497 次 |
| 最近记录: |