Кажется, есть некоторая путаница с видимостью и тем, что означают +
и -
.
В случае +
и -
они просто назначают класс вместо метода экземпляра, соответственно.Или в терминологии других языков + (void) foo
совпадает с static void foo()
, а - (void) bar
совпадает с void bar()
(например, -
является методом экземпляра).
Напредмет видимости;Строго говоря, Objective-C не имеет понятия публичного, частного и т. Д., Как и другие языки.Любое сообщение может быть отправлено любому объекту, даже если он не реализует этот метод.
Но это не означает, что вы не можете скрыть объявление метода от открытого заголовка класса.Итак, обычно у вас будет заголовочный файл, например:
@interface MyObject
- (void) foo;
- (void) secretFoo;
@end
, и вы получите реализацию (.m) в виде:
@implementation MyObject
- (void) foo {
NSLog(@"OMG FOO!");
}
- (void) secretFoo{
NSLog(@"WAT! Don't do that");
}
@end
Теперь, допустим, что метод - (void) secretFoo
является, как следует из названия, секретом.И вы бы предпочли, чтобы это не просто кто-нибудь называл.Что ж, по мере того как вещи определены, ваш публичный заголовок транслирует на весь мир существование этого секретного метода.Чтобы решить эту проблему, удалите его из публичного заголовка:
@interface MyObject
- (void) foo;
@end
Теперь никто (вообще говоря) не будет знать о вашем секретном методе.Однако есть одна небольшая проблема ... Если вы попытаетесь вызвать ваш secretMethod (обычным способом), вы получите либо предупреждение компилятора, либо даже ошибку (в зависимости от того, используете ли вы ARC).Никто не хочет ненужных предупреждений, и если вы используете ARC, это полный запрет ...
Причина предупреждения или ошибки та же, вы пытаетесь вызвать secretFoo
, нотакой метод не определен.Итак, теперь вам нужно выяснить, как определить этот метод, но не , а в публичном заголовке.Я делаю так, чтобы соответствующим образом изменить файл реализации:
@interface MyObject(Private)
- (void) secretFoo{
@end
@implementation MyObject
- (void) foo {
NSLog(@"OMG FOO!");
}
- (void) secretFoo{
NSLog(@"WAT! Don't do that");
}
@end
Теперь у вас есть метод secretFoo
, определенный для вашего собственного использования (например, без предупреждений или ошибок), но он не транслируется наworld.
Несмотря на то, что я использовал термин (Private)
, я просто реализовал категорию , которая определена только в файле реализации и поэтому обычно не видна.