Определить частные методы, которые будут использоваться методами класса - Цель C - PullRequest
1 голос
/ 24 февраля 2012

Я хочу объявить закрытые методы, которые полезны для других методов класса. Если я поставлю (+), метод будет видимым (не является частным), и если я использую (-), то во время выполнения выдается ошибка.

@interface SomeClass

+ (int) nameOfMethod;

@end

@implementation SomeClass(PrivateMethods)

+ usefulMethod; // Works but is not private
- otherUsefulMethod; // Compile but throws a error in runtime.

@end

Извините, второй блок был классом расширения.

Ответы [ 6 ]

1 голос
/ 24 февраля 2012

Кажется, есть некоторая путаница с видимостью и тем, что означают + и -.

В случае + и - они просто назначают класс вместо метода экземпляра, соответственно.Или в терминологии других языков + (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), я просто реализовал категорию , которая определена только в файле реализации и поэтому обычно не видна.

1 голос
/ 24 февраля 2012

В дополнение к тому, что говорили все, вы можете определять методы в @implementation, но не объявлять их в @interface. Таким образом, они будут видны только в файле реализации после точки введения. Использование их выше точки введения выдаст предупреждение компилятора, но будет работать. Как это:

@interface C
-(void)a;
-(void)b;
@end

@implementation C
-(void)a
{
    [self x]; //Warning, but works
}

-(void)x
{
    NSLog(@"Woohoo!");
}

-(void)b
{
    [self x]; //No warning
}
@end
1 голос
/ 24 февраля 2012

Я думаю, вы путаете.

+ usefulMethod; // + means that it is a class method
- otherMethod; // - means that is an object method
0 голосов
/ 24 февраля 2012

Вы также можете использовать sharedClasses для доступа к этим закрытым методам с теми же переменными и значениями

И там вы получаете доступ к приватным методам в классе

Класс, который я создал как NSObject, называется "test"

static test *_obj;

@implementation test

+ (test *)sharedTest {
        @synchronized(self) {

            if (_obj == nil) {

                _obj = [[self alloc] init];

                // Allocate/initialize any member variables of the singleton class here
                //_obj.member = @"";
            }
        }
        return _obj;
    }

    - (void)private1 {

    }

И когда вы называете это так, как это

[[test sharedTest] private1]

Вы можете получить доступ везде в ваших классах, и если вы храните некоторую информацию, будет такой же

Надеюсь, это поможет вам

0 голосов
/ 24 февраля 2012

Если вы пытаетесь создать закрытые методы, которые используют только другие методы класса, попробуйте поместить категорию в файл .m реализации.

0 голосов
/ 24 февраля 2012

Вы хотите использовать класс Extension.

В вашем файле реализации (.m) у вас будет следующее:

@interface SomeClass()
+(void)usefulMethod;
-(void)otherUsefulMethod;
@end

@implementation SomeClass
//... normal implementations, including from the class Extension
@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...