Приложение WatchKit аварийно завершает работу при попытке установить количество строк для таблицы

Итак, у меня есть приложение WatchKit с WKInterfaceTable в контроллере основного интерфейса, выход на раскадровку установлен, поэтому он не равен нулю, идентификатор строки таблицы также установлен и соответствует строке, которую я использую в методе setNumberOfRows:withRowType:.

Вот упрощенный код контроллера интерфейса для лучшего понимания:

class MainInterfaceController: WKInterfaceController {
  @IBOutlet weak var table: WKInterfaceTable!

  override func awakeWithContext(context: AnyObject?) {
      super.awakeWithContext(context)
      loadTableData()
  }

  private func loadTableData() {
    table.setNumberOfRows(5, withRowType: "MyTableRow")
  }
}

При вызове метода setNumberOfRows:withRowType: я получаю исключение типа NSRangeException:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 0 beyond bounds for empty array'

Это совершенно не связано с каким-либо массивом и может произойти, даже если я использую простое целое число в качестве параметра для количества строк, как в приведенном выше коде.

Вот трассировка стека этого метода и стрелка, указывающая на последний успешный шаг, после которого приложение выдает исключение:

WatchKit`-[WKInterfaceTable setNumberOfRows:withRowType:]:
    0x10e63e0ef <+0>:   pushq  %rbp
    0x10e63e0f0 <+1>:   movq   %rsp, %rbp
    0x10e63e0f3 <+4>:   pushq  %r15
    0x10e63e0f5 <+6>:   pushq  %r14
    0x10e63e0f7 <+8>:   pushq  %r13
    0x10e63e0f9 <+10>:  pushq  %r12
    0x10e63e0fb <+12>:  pushq  %rbx
    0x10e63e0fc <+13>:  pushq  %rax
    0x10e63e0fd <+14>:  movq   %rdx, %r12
    0x10e63e100 <+17>:  movq   %rdi, -0x30(%rbp)
    0x10e63e104 <+21>:  movq   %rcx, %rdi
    0x10e63e107 <+24>:  callq  *0x1800b(%rip)            ; (void *)0x000000010cc03930: objc_retain
    0x10e63e10d <+30>:  movq   %rax, %r15
    0x10e63e110 <+33>:  movq   0x28461(%rip), %rdi       ; (void *)0x000000010d2004e8: NSMutableArray
    0x10e63e117 <+40>:  movq   0x277aa(%rip), %rsi       ; "array"
    0x10e63e11e <+47>:  callq  *0x17fe4(%rip)            ; (void *)0x000000010cc06000: objc_msgSend
    0x10e63e124 <+53>:  movq   %rax, %rdi
    0x10e63e127 <+56>:  callq  0x10e63ee6e               ; symbol stub for: objc_retainAutoreleasedReturnValue
    0x10e63e12c <+61>:  movq   %rax, %rbx
    0x10e63e12f <+64>:  testq  %r12, %r12
    0x10e63e132 <+67>:  jle    0x10e63e158               ; <+105>
    0x10e63e134 <+69>:  movq   0x28205(%rip), %r13       ; "setObject:atIndexedSubscript:"
    0x10e63e13b <+76>:  xorl   %r14d, %r14d
    0x10e63e13e <+79>:  movq   %rbx, %rdi
    0x10e63e141 <+82>:  movq   %r13, %rsi
    0x10e63e144 <+85>:  movq   %r15, %rdx
    0x10e63e147 <+88>:  movq   %r14, %rcx
    0x10e63e14a <+91>:  callq  *0x17fb8(%rip)            ; (void *)0x000000010cc06000: objc_msgSend
->  0x10e63e150 <+97>:  incq   %r14
    0x10e63e153 <+100>: cmpq   %r14, %r12
    0x10e63e156 <+103>: jne    0x10e63e13e               ; <+79>
    0x10e63e158 <+105>: movq   0x281e9(%rip), %rsi       ; "setRowTypes:"
    0x10e63e15f <+112>: movq   -0x30(%rbp), %rdi
    0x10e63e163 <+116>: movq   %rbx, %rdx
    0x10e63e166 <+119>: callq  *0x17f9c(%rip)            ; (void *)0x000000010cc06000: objc_msgSend
    0x10e63e16c <+125>: movq   0x17f9d(%rip), %r14       ; (void *)0x000000010cc039b0: objc_release
    0x10e63e173 <+132>: movq   %rbx, %rdi
    0x10e63e176 <+135>: callq  *%r14
    0x10e63e179 <+138>: movq   %r15, %rdi
    0x10e63e17c <+141>: movq   %r14, %rax
    0x10e63e17f <+144>: addq   $0x8, %rsp
    0x10e63e183 <+148>: popq   %rbx
    0x10e63e184 <+149>: popq   %r12
    0x10e63e186 <+151>: popq   %r13
    0x10e63e188 <+153>: popq   %r14
    0x10e63e18a <+155>: popq   %r15
    0x10e63e18c <+157>: popq   %rbp
    0x10e63e18d <+158>: jmpq   *%rax

Есть ли способ узнать, почему или где это вообще происходит?

Изменить:

Я пытался использовать setRowTypes: и получил эту трассировку:

    0x10ccb6fb9 <+735>:  movq   0x277f0(%rip), %rsi       ; "addObject:"
    0x10ccb6fc0 <+742>:  movq   %r14, %rdx
    0x10ccb6fc3 <+745>:  callq  *%r13
    0x10ccb6fc6 <+748>:  movq   %r14, %rdi
    0x10ccb6fc9 <+751>:  movq   0x18140(%rip), %rax       ; (void *)0x000000010b27c9b0: objc_release
    0x10ccb6fd0 <+758>:  movq   %r15, %r14
    0x10ccb6fd3 <+761>:  movq   %rax, %rbx
    0x10ccb6fd6 <+764>:  callq  *%rbx
    0x10ccb6fd8 <+766>:  movq   -0x70(%rbp), %rdi
    0x10ccb6fdc <+770>:  callq  *%rbx
    0x10ccb6fde <+772>:  movq   -0x68(%rbp), %rdi
    0x10ccb6fe2 <+776>:  callq  *%rbx
    0x10ccb6fe4 <+778>:  movq   -0x58(%rbp), %rdi
    0x10ccb6fe8 <+782>:  callq  *%rbx
    0x10ccb6fea <+784>:  movq   -0x50(%rbp), %rdi
    0x10ccb6fee <+788>:  callq  *%rbx
    0x10ccb6ff0 <+790>:  movq   -0x88(%rbp), %rdi
    0x10ccb6ff7 <+797>:  movq   0x28342(%rip), %rsi       ; "setObject:atIndexedSubscript:"
    0x10ccb6ffe <+804>:  movq   %r14, %rdx
    0x10ccb7001 <+807>:  movq   %r12, %rcx
    0x10ccb7004 <+810>:  callq  *%r13
->  0x10ccb7007 <+813>:  movq   %r12, %r13

Как и раньше, он вылетает после вызова setObject:atIndexedSubscript:, так что ничего относительно строки типа строки.

Редактировать 2:

Извините, ребята, я обнаружил, что было не так: это была сторонняя библиотека с закрытым исходным кодом, которая заменяет методы подписки NSArray на objectAtIndex:/replaceObjectAtIndex:withObject:, что совершенно неправильно. Странно, что раньше у меня не было таких вариантов использования.


person Oleksandr Skrypnyk    schedule 29.04.2015    source источник
comment
Вы создали контроллер строки таблицы (подкласс NSObject) и сделали его классом строки вашей таблицы?   -  person John Rogers    schedule 30.04.2015
comment
Да, у меня есть собственный контроллер строки таблицы, но неважно, использую я его или нет — всегда одно и то же исключение.   -  person Oleksandr Skrypnyk    schedule 30.04.2015
comment
Если вы посмотрите на трассировку стека, она падает сразу после setRowTypes:. Это намекает мне, что, возможно, ваша строка типа строки неверна? Похоже, он не может найти тип строки с этим идентификатором. Вы на 100 % уверены, что идентификатором контроллера строк в инспекторе атрибутов ячейки таблицы является MyTableRow? Знаете ли вы также, что вы можете установить количество строк в инспекторе атрибутов вашей таблицы в конструкторе интерфейсов?   -  person John Rogers    schedule 30.04.2015
comment
После прочтения вопроса у меня те же подозрения, что и у Джона. Кажется, что тип строки не разрешается правильно.   -  person Mike Swanson    schedule 30.04.2015
comment
Тип строки и идентификатор контроллера строки полностью совпадают. Только что проверил с новым контроллером - все то же самое.   -  person Oleksandr Skrypnyk    schedule 30.04.2015
comment
Код, который вы предоставили, правильный, поэтому ошибка в другом месте. Еще одна идея - проверьте класс и идентификатор вашего MainInterfaceController в раскадровке.   -  person onegray    schedule 30.04.2015
comment
У меня тоже есть этот баг. Вы помните стороннюю библиотеку, которая делала забавные свизлы?   -  person Gwendal Roué    schedule 22.09.2016
comment
@GwendalRoué Я не уверен, что мы говорим об одной и той же библиотеке, потому что она больше не поддерживается. http://web.archive.org/web/20130622120954/http://www.stoeger-it.de/en/SecureIncrementalStore/   -  person Oleksandr Skrypnyk    schedule 22.09.2016
comment
ОК Александр. Спасибо за ваш ответ!   -  person Gwendal Roué    schedule 22.09.2016


Ответы (3)


Убедитесь, что вы установили тип строки в построителе интерфейса, и он соответствует типу в вашем коде.

table.setNumberOfRows(5, withRowType: "DetailsRow")

введите здесь описание изображения

person Beau Nouvelle    schedule 29.04.2015
comment
Как я уже упоминал ранее, он установлен и совпадает, так что проблема в другом. - person Oleksandr Skrypnyk; 30.04.2015
comment
Вы в итоге разобрались? - person Beau Nouvelle; 06.07.2015

Убедитесь, что вы выбрали правильный модуль (он прямо под классом в IB)

person rgreso    schedule 10.06.2017

Это работает для меня.

  1. Перейти к раскадровке
  2. Показать инспектора идентификации
  3. Для каждого контроллера строки добавьте реализацию класса (даже класс такой же простой, как фиктивный подкласс NSObject)
person Harry Ng    schedule 18.06.2018