cómo usar la bandera NS_RETURNS_INNER_POINTER

Hago una tarea para adoptar Modern Objective-C y uso la herramienta Refactoring en Xcode: Edit> Refactor> Convert to Modern Objective-C Syntax.

En el proyecto, tenía un método return const void * type. Y después de la herramienta refactor, agregue el indicador NS_RETURNS_INNER_POINTER después de este método. Verifiqué este indicador en FoundationOlderNotes pero no está claro para mí.

  1. ¿Es necesario agregar NS_RETURNS_INNER_POINTER para cualquier método o propiedad que devuelva el tipo de puntero no object?
  2. ¿Qué hace exactamente el comstackdor con el retorno del método del puntero en ARC?

NS_RETURNS_INNER_POINTER es un equivalente específico de cocoa para el objc_returns_inner_pointer método objc_returns_inner_pointer . Los documentos están aquí :

Un método Objective-C que devuelve un puntero no retenible se puede anotar con el atributo objc_returns_inner_pointer para indicar que devuelve un identificador a los datos internos de un object y que esta reference se invalidará si se destruye el object. Cuando se envía un post de este tipo a un object, la duración del object se extenderá hasta al less la más temprana de:

  • el último uso del puntero devuelto, o cualquier puntero derivado de él, en la function de llamada o
  • el set de autorelease se restaura a un estado anterior.

Razón fundamental

Justificación: no todos los resources y la memory se administran con recuentos de reference; es común que los objects administren resources privados de forma privada. Normalmente, estos resources están completamente encapsulados dentro del object, pero algunas classs ofrecen a sus usuarios acceso directo para la eficiencia. Si ARC no es consciente de los methods que devuelven pointers "internos", sus optimizaciones pueden hacer que el object propietario sea reclamado demasiado pronto. Este atributo informa a ARC que debe pisar ligeramente.

Las reglas de extensión son algo intencionadamente vagas. El límite del pool de autorelease está ahí para permitir que una implementación simple simplemente retenga y autorelease al receptor. El otro límite permite cierta cantidad de optimization. La frase "derivado de" pretende abarcar los resultados tanto de las transformaciones del puntero, como los moldes y la aritmética, y de la carga de dichos pointers derivados; Además, se aplica si dichas derivaciones se aplican directamente en el código de llamada o por otro código de utilidad (por ejemplo, la rutina de la biblioteca C strchr ). Sin embargo, la implementación nunca necesita una count para usos después de un retorno del código que llama al método que devuelve un puntero interior.

Como exception, no se requiere extensión si el receptor se carga directamente desde un object __strong con una semántica de vida precisa .

Razón fundamental

Las autoreliaciones implícitas conllevan el riesgo de inflar significativamente el uso de la memory, por lo que es importante proporcionar a los usuarios una forma de evitar estas autorizaciones. Atar esto a una semántica de por vida precisa es ideal, ya que para las variables locales esto requiere una anotación muy explícita, lo que permite que ARC confíe en el usuario con buena alegría.

Para responder a sus preguntas específicas:

  1. No, no es necesario que todos los methods o properties que devuelvan un puntero que no sea object se NS_RETURNS_INNER_POINTER con NS_RETURNS_INNER_POINTER . Solo se debe hacer si devuelve un puntero "interior" o "interior". Es decir, un puntero que se volverá inválido si el object mismo se desasigna.
  2. Lo que hace exactamente el comstackdor no se especifica. En algunas implementaciones, puede simplemente retener y autorizar el object que devolvió el puntero interno.