Использование IBOutletCollections

У меня есть 30 UILabels, которые я хочу использовать в качестве IBOutlets. Однако, когда я пытаюсь получить доступ к их свойствам UILabel, я получаю сообщение об ошибке, сообщающее, что свойство x не найдено для объекта типа 'id'. Я очень ржавый с Objective C, поэтому подозреваю, что я сделал что-то в корне неправильно. Я назначил все свои метки для IBCollection в файле xib.

.час

@interface ViewController : UIViewController
{
    IBOutletCollection(UILabel) NSArray *statPanels;
}
@property(retain) IBOutletCollection(UILabel) NSArray *statPanels;
@end

.m

@interface ViewController ()
@end

@implementation ViewController
@synthesize statPanels;

- (void)viewDidLoad
{
    [super viewDidLoad];

    statPanels = [[NSArray alloc] initWithObjects:[UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], nil ];

    [statPanels objectAtIndex:3].hidden = YES;
}

3 ответа

Решение

Если вы подключили все метки в конструкторе интерфейсов, вам не нужно инициализировать statPanels массив.

Удалить эту строку:

statPanels = [[NSArray alloc] initWithObjects:[UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], nil ];

Эта линия создает новый массив и кучу новых ярлыков, и теряет ваши торговые точки.

Кроме того, вам нужно будет разыграть, как другой ответ говорит:

((UILabel *) [statPanels objectAtIndex:3]).property = ....

Я думаю, что вы должны использовать бросок; NSArray только знает, что он содержит кучу id"S. Так что вам нужно сделать что-то вроде

((UILabel *)[array objectAtIndex:0]).someProperty

Также вы должны иметь alloc init а не только alloc, Также в вашей декларации ivar вам не нужно IBOutlet... и прочее. Просто NSArray, (В относительно новых версиях XCode вам вообще не нужно объявлять ivar.)

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

По сути, вам просто нужно удалить эту строку:

    statPanels = [[NSArray alloc] initWithObjects:[UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], [UILabel alloc], nil ];

Вы также должны знать, что распределение объектов без вызова какого-либо инициализатора обязательно закончится плохо. Вы не должны делать это. Обычный паттерн в Objective-C - это вызов [[Foo alloc] init] или похожие.

Другие вопросы по тегам