Best way of preventing other programmers from calling -init

丶灬走出姿态 提交于 2019-11-28 16:26:32

问题


When designing a class hierarchy, sometimes the subclass has added a new initWithSomeNewParam method, and it would be desirable to disable calls to the old init method inherited from the superclass.

First of all, I've read the question here, where the proposed alternatives are either override init to throw an exception at runtime, or override and set default values for properties. In my case, I don't wan't to provide default values, and I want to clearly indicate that the old method should not be called, and instead the new method with parameters should be used.

So the runtime exception are fine, but unless the code is debugged, there's no way for other programmers in the team to notice that the old method is no longer intended to be used.

If I'm correct, there's no way to mark a method as "private". So, apart from adding comments, is there a way to do this?

Thanks in advance.


回答1:


You can explicitly mark your init as being unavailable in your header file:

- (id) init __unavailable;

or:

- (id) init __attribute__((unavailable));

With the later syntax, you can even give a reason:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));

The compiler then issues an error (not a warning) if someone tries to call it.




回答2:


To add to what @DarkDust posted, you could alternatively use UNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE;

This will throw an error when a user tries to call init on an instance of this class.




回答3:


Flag it deprecated? Developers will be developers, you can't stop us all! ;-)

How do I flag a method as deprecated in Objective-C 2.0?




回答4:


initWith:Stuff and:OtherStuff should never be more than convenience constructors.

In that they effectively should call

self = [self init];

if(self)
{
    self.stuff = Stuff;
    self.other = OtherStuff;
}

so [object init] will always return an object in a predefined state, and [object initWithStuff:stuff] will return the object in the predefined state with stuff overridden.

Basically what I'm getting at is, its bad practice to discourage [object init] especially when someone subclasses your subclass in the future….




回答5:


You can sort of mark a method as "private" by defining a private extension to your class.

In your .h:

@interface MyClassName
- (void)initWithSomeNewParam:(id)param;

In your .m:

@interface MyClassName ()
- (void)init;
@end

You could also add an NSLog statement so that when anyone is running the project with an attached XCode session, they'll see console output similar to "Please don't use init, use initWithSomeNewParam: instead." Note that this is the approach Apple itself has historically taken to deprecated API calls (as well as marking deprecated in their docs).



来源:https://stackoverflow.com/questions/9634256/best-way-of-preventing-other-programmers-from-calling-init

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!