Objective-c – Is it possible to make the -init method private in Objective-C
objective-c
I need to hide (make private) the -init method of my class in Objective-C.
How can I do that?
Best Solution
NS_UNAVAILABLE
- (instancetype)init NS_UNAVAILABLE;
This is a the short version of the unavailable attribute. It first appeared in macOS 10.7 and iOS 5. It is defined in NSObjCRuntime.h as #define NS_UNAVAILABLE UNAVAILABLE_ATTRIBUTE.
Add the unavailable attribute to the header to generate a compiler error on any call to init.
-(instancetype) init __attribute__((unavailable("init not available")));
If you don't have a reason, just type __attribute__((unavailable)), or even __unavailable:
-(instancetype) __unavailable init;
doesNotRecognizeSelector:
Use doesNotRecognizeSelector: to raise a NSInvalidArgumentException. “The runtime system invokes this method whenever an object receives an aSelector message it can’t respond to or forward.”
[self release] is needed because the object was already allocated. When using ARC the compiler will call it for you. In any case, not something to worry when you are about to intentionally stop execution.
objc_designated_initializer
In case you intend to disable init to force the use of a designated initializer, there is an attribute for that:
This generates a warning unless any other initializer method calls myOwnInit internally. Details will be published in Adopting Modern Objective-C after next Xcode release (I guess).
You should use the arc4random_uniform() function. It uses a superior algorithm to rand. You don't even need to set a seed.
#include <stdlib.h>
// ...
// ...
int r = arc4random_uniform(74);
The arc4random man page:
NAME
arc4random, arc4random_stir, arc4random_addrandom -- arc4 random number generator
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdlib.h>
u_int32_t
arc4random(void);
void
arc4random_stir(void);
void
arc4random_addrandom(unsigned char *dat, int datlen);
DESCRIPTION
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8
bit S-Boxes. The S-Boxes can be in about (2**1700) states. The arc4random() function returns pseudo-
random numbers in the range of 0 to (2**32)-1, and therefore has twice the range of rand(3) and
random(3).
The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via
arc4random_addrandom().
There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically
initializes itself.
EXAMPLES
The following produces a drop-in replacement for the traditional rand() and random() functions using
arc4random():
#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))
There isn't, as others have already said, such a thing as a private method in Objective-C. However, starting in Objective-C 2.0 (meaning Mac OS X Leopard, iPhone OS 2.0, and later) you can create a category with an empty name (i.e. @interface MyClass ()) called Class Extension. What's unique about a class extension is that the method implementations must go in the same @implementation MyClass as the public methods. So I structure my classes like this:
I think the greatest advantage of this approach is that it allows you to group your method implementations by functionality, not by the (sometimes arbitrary) public/private distinction.
Best Solution
NS_UNAVAILABLE
This is a the short version of the unavailable attribute. It first appeared in macOS 10.7 and iOS 5. It is defined in NSObjCRuntime.h as
#define NS_UNAVAILABLE UNAVAILABLE_ATTRIBUTE
.There is a version that disables the method only for Swift clients, not for ObjC code:
unavailable
Add the
unavailable
attribute to the header to generate a compiler error on any call to init.If you don't have a reason, just type
__attribute__((unavailable))
, or even__unavailable
:doesNotRecognizeSelector:
Use
doesNotRecognizeSelector:
to raise a NSInvalidArgumentException. “The runtime system invokes this method whenever an object receives an aSelector message it can’t respond to or forward.”NSAssert
Use
NSAssert
to throw NSInternalInconsistencyException and show a message:raise:format:
Use
raise:format:
to throw your own exception:[self release]
is needed because the object was alreadyalloc
ated. When using ARC the compiler will call it for you. In any case, not something to worry when you are about to intentionally stop execution.objc_designated_initializer
In case you intend to disable
init
to force the use of a designated initializer, there is an attribute for that:This generates a warning unless any other initializer method calls
myOwnInit
internally. Details will be published in Adopting Modern Objective-C after next Xcode release (I guess).