2013-09-27 3 views
3

Поскольку код ViewController становится слишком большим, мне было интересно, как разбить код на несколько файлов. Вот проблема, с которой я столкнулся:Можем ли мы поместить IBOutlets в категорию?

// In the original .m file, there are bunch of outlets in the interface extension. 
@interface aViewController() 
@property (weak, nonatomic) IBOutlet UIView *contentView1; 
@property (weak, nonatomic) IBOutlet UIView *contentView2; 
@property (weak, nonatomic) IBOutlet UIView *contentView3; 
@end 

Я хочу разбить файл на 3 категории в соответствии с тремя различными видами.

// In category aViewController+contentView1.m file 
@interface aViewController() 
@property (weak, nonatomic) IBOutlet UIView *contentView1; 
@end 

Если удалить исходный contentView1 выход, однако, он не работает.

Вопрос
Почему я должен держать contentView1 отверстие в оригинальном .m файле?

ответ

7

Объективный-C category не позволяет добавить дополнительные свойства к классу, только методы. Таким образом, вам не разрешено добавлять дополнительные IBOutlet s в пределах category. Категория обозначается аналогично @interface aViewController (MyCategoryName) (обратите внимание на имя, указанное внутри круглых скобок).

Вы можете, однако, добавить дополнительные свойства в class extension. A class extension обозначается с тем же именем, что и исходный класс, за которым следует (). В вашем примере кода, обе строки, относящиеся к @interface aViewController() фактически объявить class extension (не category), независимо от того, header файл на самом деле они в.

Кроме того, вы позволили создать несколько расширений класса через несколько различных заголовков. Фокус в том, что вам нужно импортировать их правильно.

В примере рассмотрим класс под названием ViewController. Мы хотим создать ViewController+Private.h и ViewController+Private2.h, которые имеют дополнительные выходы privateView, которые по-прежнему будут доступны в пределах ViewController.m.

Вот как мы можем это сделать:

ViewController.h

// Nothing special here 

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 
// some public properties go here 
@end 

ViewController + Private.h

// Note that we import the public header file 
#import "ViewController.h" 

@interface ViewController() 
@property (nonatomic, weak) IBOutlet UIView *privateView; 
@end 

ViewController + Private2.h

// Note again we import the public header file 
#import "ViewController.h" 

@interface ViewController() 
@property (nonatomic, weak) IBOutlet UIView *privateView2; 
@end 

ViewController.m

// Here's where the magic is 
// We import each of the class extensions in the implementation file 
#import "ViewController.h" 
#import "ViewController+Private.h" 
#import "ViewController+Private2.h" 

@implementation ViewController 

// We can also setup a basic test to make sure it's working. 
// Just also make sure your IBOutlets are actually hooked up in Interface Builder 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.privateView.backgroundColor = [UIColor redColor]; 
    self.privateView2.backgroundColor = [UIColor greenColor]; 
} 

@end 

И это, как мы можем это сделать.

Почему Ваш код не работал

Скорее всего, вы, вероятно, перепутали #import заявление. Чтобы это исправить,

1) Убедитесь, что каждый class extension файл импортирует заголовок исходного класса (т.е. ViewController.h)

2) Убедитесь, что реализация класса импорта файлов (т.е. ViewController.m), каждый из заголовков расширения класса.

3) Убедитесь, что заголовок класса (то есть ViewController.h файл) не импорта любого из заголовков расширения класса.

Для справки вы также можете проверить документы Apple по телефону Customizing Existing Classes.

+0

Я не был на 100% уверен в своем первоначальном ответе, поэтому я проверил его и нашел, что он неправильный. Я обновил ответ с правильной информацией. : D –

+0

интересно .. я всегда задавался вопросом, что означал '()', когда я видел это в файле m, я решил, что это просто способ пользователя obj-c '@ property' в частном порядке (т. Е. Он автоматически генерирует аксессоры .. но для доступа только в файле .m) – abbood

+1

@abbood, Да, наиболее распространенное использование расширений класса - это скрыть переменные, которые вы не хотите публично видимым. Обычно расширения класса действительно помещаются в файл реализации класса , Но эй, ты тоже можешь это сделать. : D –

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