webapp tag name capable apps apple app ios objective-c swift automatic-ref-counting

ios - tag - Recuento de referencias en ARC



web apps iphone (4)

Tengo un poco de confusión en el recuento de referencias ARC ¿Podría decirme cuál será el recuento de referencias del código de abajo?

var vc1 = UIViewController() var vc2 = vc1 var vc3 = vc2 weak var vc4 = vc3

La pregunta es cuál será el:

  • recuento de referencia de vc1?
  • recuento de referencia de vc2?
  • recuento de referencia de vc3?
  • recuento de referencia de vc4?

1,2,3,4 - el conteo de referencia será 3

La única excepción cuando el recuento de referencias no se incrementará: cuarta línea, debido a un modificador débil


Aquí, vc1 , vc2 , vc3 refieren al mismo objeto. Por lo tanto, el recuento de referencia de ese objeto es 3. Cuando vc4 refiere al mismo objeto, ya que es una referencia débil, el recuento de referencia no se incrementará en 1. Entonces, el recuento de referencia después de esto también será 3

  1. El recuento de referencia del objeto UIViewController creado y referido por vc1 después de la primera línea de código es 1.

    var vc1:UIViewController? = UIViewController() // strong reference

  2. Después de vc2 refiere al mismo objeto que vc1 . La cuenta de referencia del objeto se convierte en 2.

    var vc2:UIViewController? = vc1 // strong reference

  3. Después de vc3 refiere al mismo objeto que vc1 y vc2 . La cuenta de referencia del objeto se convierte en 3.

    var vc3:UIViewController? = vc2 // strong reference

  4. Después de vc4 refiere al mismo objeto que vc1 , vc2 y vc3 . Como vc4 es una referencia débil, el recuento de referencias no se incrementará. Eso significa que la cuenta sigue siendo 3.

    weak var vc4:UIViewController? = vc3 // weak reference

Lo que significa:

Ejecuta el siguiente código.

vc1 = nil; // reference count = 3-1 = 2 vc2 = nil; // reference count = 2-1 = 1 vc3 = nil; // reference count = 1-1 = 0 and object is destroyed

Ahora, imprima el valor de vc4 . Será nil . Esto sucede porque la cuenta de referencia del objeto se convierte en cero y todas las variables se refieren al mismo objeto.

Editar:

El uso de CFGetRetainCount en el siguiente código da los siguientes resultados como se indica aquí:

var vc1:NSDate? = NSDate() print(CFGetRetainCount(vc1)) // 2 - I expected this to be 1 as only one variable is strongly referring this object. var vc2:NSDate? = vc1 print(CFGetRetainCount(vc1)) // 3 - reference count incremented by 1 (strong reference) var vc3:NSDate? = vc2 print(CFGetRetainCount(vc3)) // 4 - reference count incremented by 1 (strong reference) weak var vc4:NSDate? = vc1 print(CFGetRetainCount(vc1)) // 4 - reference count not incremented (weak reference) vc1 = nil print(CFGetRetainCount(vc2)) // 3 - reference count decremented by 1 (strong reference removed) vc2 = nil print(CFGetRetainCount(vc3)) // 2 - reference count decremented by 1 (strong reference removed) vc3 = nil print(vc4) // nil - reference count should be decremented by 1 (last strong reference removed) // Also due to the final line vc3 = nil, reference count should become zero // However, we can''t use `CFGetRetainCount` to get reference count in this case // This is due to the final strong reference being removed and object getting destroyed

La razón por la cual CFRetainCount está dando 2 en la primera línea se ha discutido here . Gracias a @CodaFi y @Sahil por su discusión en los comentarios


En mi opinión, vc1 a vc3 incrementa el recuento de retenciones y la propiedad por defecto es strong hasta que los especifiquemos como weak .

strong: Strong generalmente es usado por una clase para establecer la propiedad de un objeto. Aumenta el recuento de retenciones (algo con lo que ARC se encarga de usted), básicamente mantiene el objeto al que se apunta en la memoria hasta que la instancia de la clase deja de señalarlo. Por lo general, esto es lo que desea, pero allí puede causar algo llamado "ciclo de retención".

En el caso de vc4 como decs como weak :

débil: Esto le da un puntero a un objeto, pero no reclama la propiedad, y no aumenta la cuenta de retención. Básicamente, mantiene un puntero válido a un objeto siempre que otra clase lo apunte con fuerza. Si nada más está intentando retenerlo, el puntero débil se establece automáticamente en nulo.


Puede usar la función CFGetRetainCount para el recuento de ref.

var vc1 = UIViewController() var vc2 = vc1 var vc3 = vc2 weak var vc4 = vc3 print(CFGetRetainCount(vc1)) //4 print(CFGetRetainCount(vc2)) //4 print(CFGetRetainCount(vc3)) //4 print(CFGetRetainCount(vc4)) //4

También puede consultar este Obtener Recuento de Ref.