IPhone - загрузить UIView из файла nib?

Я подклассифицирую UIView, пытаясь загрузить представление, которое я сбросил в конструкторе интерфейса из файла nib. Я получаю следующую ошибку в обратной линии:

Завершение приложения из-за неотображенного исключения "NSGenericException", причина: "Этот кодер требует, чтобы замененные объекты возвращались из initWithCoder:"

- (id)initWithCoder:(NSCoder *)aDecoder
{
    [super initWithCoder:aDecoder];
    NSArray *objects = [[NSBundle mainBundle]
                        loadNibNamed:@"MyView" 
                        owner:nil 
                        options:nil];
    if (self = [objects objectAtIndex:0])
    {
    }
    return [self retain];
}

Ответ 1

Вы делаете что-то очень странное)

loadNibNamed:owner:options: вызовет initWithCoder:, чтобы создать экземпляр вашего представления из xib. Но вы вызываете loadNibNamed:owner:options: из initWithCoder:. Бесконечная рекурсия?

Чтобы загрузить представление из xib, вы можете сделать следующее:

@implementation MyView

+ (MyView*) myView
{
  NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:nil options:nil];
  return [array objectAtIndex:0]; // assume that MyView is the only object in the xib
}

@end

Ответ 2

Вместо того, чтобы делать self = [objects objectAtIndex:0], вы должны пройти через массив и убедиться, что вы получаете нужный объект, например:

for (id object in objects) {
    if ([object isKindOfClass:[YourClassName class]])
        self = (YourClassName*)object;
}   

Тем не менее, я всегда делал этот слой и вытаскивал ссылку прямо из UIViewController. Это сломает слой абстракции, поскольку класс, который просто хочет использовать представление, должен знать, что Nib его в:

UIViewController *vc = [[UIViewController alloc] initWithNibName:@"MyView" bundle:nil];
YourClassName* view = (YourClassName*)vc.view;
[vc release];