Inout не работает с бросками объекта SubClass Невозможно передать неизменное значение в качестве аргумента inout - PullRequest
0 голосов
/ 28 июня 2018

у меня два блока кодов

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
  // BLOCK 1 Which is not working 
    guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

    var plane = Plane(with: planeAnchor) //IT IS SUBCLASS OF SCNNode
    var geo = plane.geometry
    plane.transform = SCNMatrix4MakeRotation(-.pi / 2, 1, 0, 0)

    update(&plane, withGeometry: plane.geo, type: .static)

   //Up here Cannot pass immutable value as inout argument: implicit conversion from 'Plane' to 'SCNNode' requires a temporary

    node.addChildNode(plane)

   // BLOCK 2 Which is working 


    let width = CGFloat(planeAnchor.extent.x)
    let height = CGFloat(planeAnchor.extent.z)
    let plane1 = SCNPlane(width: width, height: height)

    plane1.materials.first?.diffuse.contents = UIColor.white.withAlphaComponent(0.5)

    var planeNode = SCNNode(geometry: plane1)

    let x = CGFloat(planeAnchor.center.x)
    let y = CGFloat(planeAnchor.center.y)
    let z = CGFloat(planeAnchor.center.z)
    planeNode.position = SCNVector3(x,y,z)
    planeNode.eulerAngles.x = -.pi / 2

    update(&planeNode, withGeometry: plane1, type: .static)
    // WORKING FINE

    node.addChildNode(planeNode)

    self.planes[anchor.identifier] = plane

}

BLOCK1

У меня есть подкласс class Plane: SCNNode, когда я пытаюсь передать его объект в функцию, которая требует inout, это показывает мне ошибку

Невозможно передать неизменяемое значение в качестве аргумента inout: неявное преобразование из «плоскости» в «SCNNode» требует временного

Пока я удаляю подкласс, он работает нормально

Почему это быстрый баг или я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Inout не будет работать с Subclass

Вот пример

class SuperClass {
    var name = "Prashant"

}

class TestObject:SuperClass {
}


func updateTemp ( object:inout SuperClass) {
    object.name = "P.T"
}

Теперь, когда вы создаете TestObject объект, который является подклассом SuperClass, он не позволит это сделать.

var obj  = TestObject()
self.updateTemp(object: &obj) // Cannot pass immutable value as inout argument: implicit conversion from 'TestObject' to 'SuperClass' requires a temporary
print(obj.name)

Как это исправить

Три способа

1) создать объект с var obj:SuperClass = TestObject()

2) На самом деле это не обязательно должно быть inout, поскольку класс является ссылочным типом

3) Создайте функцию Generic, как она (Generic - это здорово !!)

func updateTemp<T:SuperClass> ( object:inout T) {
    object.name = "P.T"
} 

Надеюсь, это кому-нибудь пригодится

0 голосов
/ 28 июня 2018

Поскольку класс Plane инициализируется с помощью «init (_ anchor: ARPlaneAnchor)», даже если он объявлен как класс SCNNode, он возвращает экземпляр, отличный от чистого SCNNode, как в блоке 2.

Я не эксперт по теме мутации, но думаю, что в блогах Apple есть интересный документ Роль мутации в безопасности

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

...