2010-04-25 4 views
3

Я новичок в iPhone и объективе c. Я потратил часы и часы и часы на чтение документов и пытался понять, как все работает. У меня есть RTFM или, по крайней мере, в этом процессе.Использование интерфейса Builder эффективно

Основная проблема заключается в том, что я хочу понять, как указать, куда передается событие, и единственный способ, которым я смог это сделать, - указать делегатов, но я уверен, что в IB легче и быстрее ,

Итак, пример. Допустим, у меня есть 20 разных видов и контроллеров и один MyAppDelegate. Я хочу, чтобы иметь возможность создавать все эти различные Xib-файлы в IB и добавлять все количество кнопок и текстовых полей и т. Д., А затем указывать, что все они производят какое-то событие в объекте MyAppDelegate. Для этого я добавил объект MyAppDelegate в каждый контроллер представления в виде списка IB. Затем я создал метод IBAction в MyAppDelegate в XCode и вернулся к IB и связал все события с объектом MyAppDelegate в каждом файле Xib.

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

Я предполагаю, что каждый файл Xib помещает указатель объекта MyAppDelegate, который не имеет никакого отношения к возможному адресу MyAppDelegate, который будет фактически создан во время выполнения.

Так что мой вопрос ... как я могу это сделать? !!!

ответ

4

Если вы создаете экземпляр MyAppDelegate в каждом файле nib, то да, в конечном итоге вы получаете множество разных экземпляров класса при загрузке всех загрузок. Делегат приложения не идентифицируется по классу или даже протоколу, а скорее как объект, на который указывает свойство delegate экземпляра приложения. Чтобы найти истинного делегата приложения, вам нужно спросить сам объект приложения для его делегата.

У вас должны быть все контроллеры представлений из класса контроллера родительского представления, у которого есть свойство appDelegate. Реализовать что-то вроде этого:

#import "MyAppDelegateClass.h" 

@interface ViewControllerBaseClass :UIViewController { 
    MyAppDelegateClass *appDelegate; 
} 
@property(nonatomic, retain) *appDelegate; 

@end 

@implementation ViewControllerBaseClass 
@synthesize appDelegate; 

-(MyAppDelegateClass *) appDelegate{ 
    self.appDelegate=(MyAppDelegateClass *)[[UIApplication sharedInstance] delegate]; 
    return appDelegate; 
} 
@end 

Когда контроллер зрения нуждается в приложение делегата он просто называет self.appDelegate. Если вы хотите получить доступ к атрибуту делегата приложения, используйте self.appDelegate.attributeName.

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

+0

Если бы я сказал @property (неатомический, сохранить) IBOutlet MyAppDelegateClass * AppDelegate , а затем подклассы каждого из моего viewcontrollers из этой базы ViewController и затем добавляли различные методы IBAction в моем AppDelegate само то, конечно, есть какой-то способ подключения эти IBOutlets в построителе интерфейса вместо кода? До сих пор я сделал это программно, просто установив свойство appDelegate для себя при загрузке контроллеров представлений из MyAppDelegateClass, но я думаю, что строка [UIApplication ...] будет лучше. Но разве нет пути в IB? – twerdster

+1

Делегат приложения - это конкретный экземпляр. Вы должны указать на этот конкретный экземпляр или не дойти до фактического делегата. Просто давая классу выход, не позволяет его подклассам указывать на конкретные экземпляры. Каждый из этих торговых точек должен ссылаться на конкретный экземпляр делегирования приложения, который объекты приложения используют в качестве своего делегата. – TechZen

+1

Файлы Nib предназначены для модульной работы и имеют ограниченную область действия. По дизайну они не зависят от и не могут видеть все приложение или даже объект приложения. Таким образом, только актив, принадлежащий самому объекту приложения (обычно MainWindo.nib), может видеть активный делегат. – TechZen

0

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

1

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

Контроллеры представлений (подклассы UIViewController) должны взаимодействовать с XIB. Наличие определенного вида поведения в контроллерах представлений делает приложение намного проще в управлении и обслуживании. Как правило, должно быть 0 или 1 XIB для каждого контроллера представления (более сложное).Вы настроили взаимодействие с представлениями с помощью шаблона Target/Action с IBOutlets и IBActions (см. here для полного руководства). Как правило, плохая идея сделать контроллеры представлений или XIB зависимыми от делегата приложения (поскольку сокращение зависимостей снова упрощает управление кодом).

+0

Хорошо, тогда я задам несколько иной вопрос. Как создать один контроллер представлений, который управляет несколькими различными представлениями, где каждый вид определен в отдельных файлах nib. Допустим, я строю 5 представлений в 5 разных норах, ничего больше в иерархии ниб, кроме представлений. Теперь я создаю наконечник с контроллером вида, но нет представлений. Как я могу инициализировать MyAppViewController с указанным представлением времени выполнения. Есть ли в UIView вариант для этого? Должен ли я затем устанавливать владельца файлов каждого типа nib-only-a-view для типа MyAppViewController? Или как это сделать? – twerdster

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