переопределен при уже освобождении (объекту присвоено значение nil) для SCNNodes в iOS SceneKit

#ios #xcode #memory-management #bounding-box #scnnode

#iOS #xcode #управление памятью #ограничивающий прямоугольник #scnnode

Вопрос:

Обращаясь за помощью по проблеме, приношу извинения, если это очевидно, поскольку у меня нет опыта. Моя среда — Xcode 10.1 и Swift.

 weak var node = Label(geometry: label, labelType: labelType, index: index)
if node != nil {
     transformTextNodeCenter(for: node!) //move pivot to center
     node!.scale = SCNVector3(x: parameters.textScaleRatio, y: parameters.textScaleRatio, z: parameters.textScaleRatio) //rescale the textnode
     print(node!) //print no.1
     print(node!.labelType, node!.index, node!.boundingBox) //print no.2
     let textWidth = node!.boundingBox.max.x - node!.boundingBox.min.x //<- This is the line generate error
     let textHeight = node!.boundingBox.max.y - node!.boundingBox.min.y
     let maxWidth = max(textWidth, recordedWidth)
     node!.position = position   SCNVector3(x: extra.x * textWidth, y: extra.y * textWidth, z: extra.z * textWidth)
     node!.eulerAngles = eulerAngles
     node!.name = String("(name)(text)")
     self.label[labelArray].append(node!)
     //self.label.insert(node)
     self.addChildNode(node!)
} else {
    print("node == nil")
}
  

Цель функции — добавить SCNText в мою сцену, но есть вероятность, что мой textnode будет освобожден в середине функции (я помещаю его в цикл for, и он выполняется случайным образом несколько циклов до сбоя) см. рис. 1

Похоже, что узел инициализирован правильно, поскольку он может передавать if node != nil" statement и печатать № 2 следующим образом

«строка 0 (минимум: __ C.SCNVector3(x: 0.7861328, y: 1.2421875, z: 0.0), максимум: __C.SCNVector3(x: 18.325195, y: 10.211914, z: 0.0))»

Это заставляет меня поверить, что я успешно получил BoundingBox текстового узла. Но в следующей строке произошел сбой «пусть TextHeight = node!.BoundingBox.max.y — узел!.BoundingBox.min.y».

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

Я прочитал какой-то пост на so и следую инструкции, чтобы установить точку останова для objc_overrelease_during_dealloc_error, но это приводит меня к «SCNBoundingVolume.BoundingBox.getter»

 libswiftSceneKit.dylib(extension in SceneKit):__C.SCNBoundingVolume.boundingBox.getter : (min: __C.SCNVector3, max: __C.SCNVector3):
0x10205167c < 0>:  sub    sp, sp, #0x30             ; =0x30 
0x102051680 < 4>:  stp    x29, x30, [sp, #0x20]
0x102051684 < 8>:  add    x29, sp, #0x20            ; =0x20 
0x102051688 < 12>: nop    
0x10205168c < 16>: ldr    x8, #0x29d4               ; (void *)0x000000021e95aa28: SCNVector3Zero
0x102051690 < 20>: ldp    w9, w10, [x8]
0x102051694 < 24>: ldr    w8, [x8, #0x8]
0x102051698 < 28>: stp    w9, w10, [sp, #0x10]
0x10205169c < 32>: str    w8, [sp, #0x18]
0x1020516a0 < 36>: stp    w9, w10, [sp]
0x1020516a4 < 40>: str    w8, [sp, #0x8]
0x1020516a8 < 44>: nop    
0x1020516ac < 48>: ldr    x1, #0x2e9c               ; "getBoundingBoxMin:max:"
0x1020516b0 < 52>: add    x2, sp, #0x10             ; =0x10 
0x1020516b4 < 56>: mov    x3, sp
0x1020516b8 < 60>: mov    x0, x20
0x1020516bc < 64>: bl     0x102053310               ; symbol stub for: objc_msgSend
0x1020516c0 < 68>: ldr    w1, [sp, #0x18]
0x1020516c4 < 72>: ldr    x0, [sp, #0x10]
0x1020516c8 < 76>: ldr    w8, [sp]
0x1020516cc < 80>: ldur   x2, [sp, #0x4]
0x1020516d0 < 84>: bfi    x1, x8, #32, #32
0x1020516d4 < 88>: ldp    x29, x30, [sp, #0x20]
0x1020516d8 < 92>: add    sp, sp, #0x30             ; =0x30 
0x1020516dc < 96>: ret    
  

И я не могу найти способ это интерпретировать.

P.S. сильная переменная по-прежнему приводит к сбою, но с другим сообщением об ошибке «EXC_BAD_ACCESS», как показано на рис. 4.

рис. 1 для сбоя

pic2 для нулевого узла

рис. 3 для нулевого узла

pic3 для сильной переменной вместо слабой

Комментарии:

1. Я думаю, что weak var node объявление вызывает проблему. Вы пробовали использовать var node вместо weak var node этого?

2. Привет, Akhilrajtr, к сожалению, изменение его на strong не работает, он по-прежнему вылетает в том же месте.

3. Э-э, этого не должно быть weak . Он не может завершиться с той же ошибкой, если это не так weak . У вас даже есть предупреждение выше, экземпляр будет немедленно освобожден

4. Привет, Султан, я думаю, что причиной может быть использование weak, но strong var также выходит из строя. Хотя у него другое сообщение об ошибке, не уверен, может ли это помочь?

5. Кроме того, мне любопытно, почему на слабом узле будет немедленно отображаться предупреждение об освобождении? Я все еще обращаюсь к нему, пока он не будет добавлен в дочерний массив, верно?