2012-03-12 2 views
7

Я пытаюсь объявить приватный @interface для категории, в .m файле.Можно ли объявить второй @interface для категории?

Для нормального класса я хотел бы сделать:

@interface ClassA() 

@end 

@implementation ClassA 

@end 

и она будет работать гладко.

Для класса с категориями Я пробовал:

@interface ClassA (CategoryA)() 

@end 

@implementation ClassA (CategoryA) 

@end 

но дает все вроде различных ошибок. Я пытаюсь «расширить» категорию, способ расширения класса через этот синтаксис @interface ClassA().

Я хочу иметь частные методы для категории, и я хотел знать, если в ДОПОЛНЕНИИ к открытому интерфейсу я могу поместить вторую категорию @interface в .m-файл, который не выставляет экземпляров переменных и методов вне самого класса.

Что-то вроде этого:

ClassA + categoryA.h

@interface ClassA (CategoryA) 

<some public methods> 

@end 

ClassA + categoryA.m файл

@interface ClassA (CategoryA) 

<some private methods> 

@end 


@implementation ClassA (CategoryA) 

<here I want to be able to call the private methods above> 

@end 

Сейчас это дает мне предупреждение в Xcode:

Повторяющееся определение категории 'Cate goryA 'по интерфейсу' ClassA '

Есть ли способ получить это поведение?

+1

Что причина -1? Я сделал какую-то ошибку? –

+0

Скучно, вы должны были сообщить об ошибках, о которых вы говорили. Но я думаю, что достаточно ясно для ответа. – fbernardo

+2

Ошибки здесь не актуальны, они явно связаны с тем, что xCode не понимает синтаксис, который я пытаюсь применить. –

ответ

12

Нет, вы не можете объявить два интерфейса для одной категории. Вы можете сделать одну из двух вещей:

Englebert + Humperdinck.ч

#import "Englebert.h" 

@interface Englebert (Humperdinck) 

- (void) croon; 

@end 

Вы можете объявить другой категории с другим именем, чтобы содержать частные методы. Они могут быть использованы в том же файле, где объявлен частный интерфейс категории:

Englebert + Humperdinck.m

#import "Englebert+Humperdinck.h" 

@interface Englebert (HumperdinckPrivate) 

- (void) warmUp; 

@end 

@implementation Englebert (HumperdinckPrivate) 

- (void)warmUp { 
    NSLog(@"Warm up"); 
} 

@end 

@implementation Englebert (Humperdinck) 

- (void)croon { 
    [self warmUp]; 
    NSLog(@"Croon"); 
    // etc. 
} 

@end 

Другой вариант просто не объявить частных методов. Если вы просто определяете их в блоке реализации, вы можете использовать их в любой точке в этом файле после их определения (и для последней версии Xcode/LLVM порядок на самом деле неважен) - необъявленные методы могут использоваться в любом месте файл, в котором они определены). Никакие другие файлы не смогут увидеть эти методы.

Englebert + Humperdinck.m

#import "Englebert+Humperdinck.h" 

@implementation Englebert (Humperdinck) 

/* Undeclared private method */ 
- (void)warmUp { 
    NSLog(@"Warm up"); 
} 

- (void)croon { 
    [self warmUp]; 
    NSLog(@"Croon"); 
    // etc. 
} 

@end 
+0

Большое спасибо Джошу. Очень хорошо объяснено. Я не знал, что с последним Xcode порядок выполнения уже не важен, я пойду так. Приветствия. –

+0

Добро пожаловать! –

+0

Привет Я объявляю вторую категорию в файле реализации первой категории (так же, как вы показали здесь). Но я не писал @implementation для второй категории, я просто реализую их в реализации первой категории. Xcode не жаловался на это, так что это «лучший» вариант? B/C моей целью здесь является объявление этих частных методов, и я могу сохранить некоторые типизации. – Qiulang

1

ли

@interface ClassA (CategoryA) 

@end 

@implementation ClassA (CategoryA) 

@end 

Вместо. В категориях не может быть экземпляра varibles. И о каких ошибках вы говорите?

0

@interface ClassA() является anonymous category, и вы можете использовать их как интерфейсы и определить реализацию в реализации ClassA. @interface ClassA (CategoryA)() является синтаксической ошибкой и следует читать @interface ClassA (CategoryA)

EDIT:

Для создания частных методов класса, в этом классе .m файл, который вы бы:

@interface ClassA() 
    // Private functions declared 
@end 

@implementation ClassA 
    // Private functions defined 
    // Other functions defined 
@end 

То же самое можно сделать для именованные категории, однако вам необходимо будет определить реализацию отдельно, чтобы избежать предупреждений. Опять же, в .m файле:

@interface ClassA (hidden) 
    // Private functions declared 
@end 

@implementation ClassA (hidden) 
    // Private functions declared 
@end 

@implementation ClassA 
    // Other functions defined 
@end 
+0

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

+0

см. Мое обновление ... –

+0

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

Смежные вопросы