EXC_BAD_ACCESS в [окно addSubview: viewcontroller.view] - PullRequest
3 голосов
/ 16 июля 2010

У меня есть два универсальных приложения ... одно выдает ошибку EXC_BAD_ACCESS, когда я делаю это в делегате приложения:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    ScrollViewController *vc = [[ScrollViewController alloc] init];
    [window addSubview:vc.view]; // EXC_BAD_ACCESS here
    [window makeKeyAndVisible];

    return YES;
}

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

Эта проблема сводит меня с ума.Вот реализация ScrollViewController:

@implementation ScrollViewController

- (void)loadView {
    [super loadView];
    UIScrollView *s = [[UIScrollView alloc] initWithFrame:[[self view] bounds]];

    NSArray *a = [[NSBundle mainBundle] loadNibNamed:@"JCEKKeyboard" owner:self options:nil];

    UIView *v = [a objectAtIndex:0];

    [s setContentSize:CGSizeMake(400, 500)];
    [s addSubview:v];
    [[self view] addSubview:s];
}

Ответы [ 2 ]

2 голосов
/ 25 марта 2011

Помните, что когда вы добавляете подпредставления, т.е. [someView addSubview:someOtherView], вы потенциально добавляете целый граф подпредставлений (подпредставления someOtherView). Если виден someView, это вызовет рендеринг на новом графике добавленного вами подпредставления. Поэтому, если какое-либо из подпредставлений в новом графике не сохранено правильно, вы можете получить эту ошибку. Вы должны проверить всю иерархию представлений, которую вы добавляете.

Используйте следующие команды GDB в вашей консоли:

Чтобы проверить, является ли отдельный объект действительным

po [someView description]

Чтобы проверить подпредставления someView

po [someView subviews]  

Для проверки отдельных подпредставлений (например, первый элемент подпредставления 0)

po [[someView subviews] objectAtIndex:0]

Наконец, чтобы проверить всю иерархию представлений одновременно

po [someView recursiveDescription]

Эти команды, особенно recursiveDescription, также очень полезны для устранения неполадок макета.

1 голос
/ 16 июля 2010

init не должен создавать представление, это делает loadView. Вызов метода получения представления (vc.view), когда view равен nil, вызовет loadView.

Прочтите документацию для loadView , вы используете ее неправильно. Вы не должны вызывать super из loadView, и вы должны установить свойство view в контроллере представления. Вы не должны вызывать геттер для view [self view] из loadView, потому что геттер вызывает loadView. Вы должны создать представление в loadView и установить свойство представления.

Примерно так:

- (void)loadView {
    NSArray *a = [[NSBundle mainBundle] loadNibNamed:@"JCEKKeyboard" owner:self options:nil];  
    UIView *v = [a objectAtIndex:0]; 

    CGRect frame = [UIScreen mainscreen].applicationFrame;
    UIScrollView *s = [[UIScrollView alloc] initWithFrame: frame];
    [s setContentSize:CGSizeMake(400, 500)];
    [s addSubview:v];

    self.view = s;
}
...