Лучший способ определить закрытые методы для класса в Objective C

352
задан 6 revs, 5 users 59% 3 March 2016 в 09:30
поделиться

6 ответов

Нет, как другие уже сказали, такая вещь как закрытый метод в Objective C. Однако начиная в Objective C 2.0 (значение Mac OS X Leopard, iPhone OS 2.0, и позже) можно создать категорию с пустым названием (т.е. @interface MyClass ()) названный Расширение Класса . То, что уникально о расширении класса, - то, что реализации метода должны войти в тот же @implementation MyClass как открытые методы. Таким образом, я структурирую свои классы как это:

В.h файле:

@interface MyClass {
    // My Instance Variables
}

- (void)myPublicMethod;

@end

И в.m файле:

@interface MyClass()

- (void)myPrivateMethod;

@end

@implementation MyClass

- (void)myPublicMethod {
    // Implementation goes here
}

- (void)myPrivateMethod {
    // Implementation goes here
}

@end

я думаю, что самое большое преимущество этого подхода состоит в том, что он позволяет Вам группировать свои реализации метода функциональностью, не (иногда произвольный) общедоступное/частное различие.

434
ответ дан 3 revs, 3 users 97% 23 November 2019 в 00:24
поделиться

В Objective C нет действительно "закрытого метода", если время выполнения может удаться, какая реализация использовать его сделает это. Но но это вовсе не значит что нет методов, которые не являются частью зарегистрированного интерфейса. Для тех методов я думаю, что категория прекрасна. Вместо того, чтобы помещать @interface наверху.m файла как Ваша точка 2, я поместил его в ее собственный.h файл. Соглашение я следую (и видели в другом месте, я думаю, что это - соглашение Apple, поскольку XCode теперь оказывает автоматическую поддержку ему), должен назвать такой файл в честь его класса и категории с + разделение их, таким образом @interface GLObject (PrivateMethods) может быть найден в GLObject+PrivateMethods.h. Причина обеспечения заголовочного файла состоит в том так, чтобы можно было импортировать его в классах модульного теста:-).

Между прочим, до реализации/определения методов около конца.m файла затронут, можно сделать это с категорией путем реализации категории у основания.m файла:

@implementation GLObject(PrivateMethods)
- (void)secretFeature;
@end

или с расширением класса (вещь Вы называете "пустую категорию"), просто определите те методы в последний раз. Методы Objective C могут определяться и использоваться в любом порядке в реализации, таким образом, нет ничего для остановки Вас помещающий "частные" методы в конце файла.

Даже с расширениями класса я буду часто создавать отдельный заголовок (GLObject+Extension.h) так, чтобы я мог использовать те методы при необходимости, имитируя "друга" или "защищенную" видимость.

, Так как этот ответ был первоначально записан, компилятор лязга начал делать две передачи для методов Objective C. Это означает, что можно постараться не объявлять "частные" методы полностью, и являются ли они выше или ниже сайта вызова, которым они будут найдены компилятором.

50
ответ дан 23 November 2019 в 00:24
поделиться

В то время как я не эксперт Objective C, я лично просто определяю метод в реализации моего класса. Предоставленный, это должно быть определено прежде (выше) любых методов, назвав его, но определенно требуется наименьшее количество объема работы, чтобы сделать.

37
ответ дан Andy 23 November 2019 в 00:24
поделиться

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

//.h file
@interface MyClass : Object
{
    int test;
}
- (void) someMethod: anArg;

@end


//.m file    
@implementation MyClass

static void somePrivateMethod (MyClass *myClass, id anArg)
{
    fprintf (stderr, "MyClass (%d) was passed %p", myClass->test, anArg);
}


- (void) someMethod: (id) anArg
{
    somePrivateMethod (self, anArg);
}

@end
14
ответ дан 2 revs 23 November 2019 в 00:24
поделиться

Нет никакого способа обойти выпуск № 2. Это - просто путь компилятор C (и следовательно компилятор Objective C) работа. При использовании редактора XCode функциональное всплывающее окно должно помочь перейти @interface и @implementation блоки в файле.

1
ответ дан Barry Wark 23 November 2019 в 00:24
поделиться

Если вы хотите избежать блока @interface вверху, вы всегда можете поместить частные объявления в другой файл MyClassPrivate.h не идеально, но это не загромождает реализацию.

MyClass.h

interface MyClass : NSObject {
 @private
  BOOL publicIvar_;
  BOOL privateIvar_;
}

@property (nonatomic, assign) BOOL publicIvar;
//any other public methods. etc
@end

MyClassPrivate.h

@interface MyClass ()

@property (nonatomic, assign) BOOL privateIvar;
//any other private methods etc.
@end

MyClass.m

#import "MyClass.h"
#import "MyClassPrivate.h"
@implementation MyClass

@synthesize privateIvar = privateIvar_;
@synthesize publicIvar = publicIvar_;

@end
2
ответ дан 23 November 2019 в 00:24
поделиться