Extensions

modifica

Les extensions permeten afegir funcionalitats a una class, estructura, enumeració o protocol. Això permet tenir accés a extend types als quals no es té accés al codi font original.

Les extensions de Swift permeten:

  • Afegir propietats computades i propietats de tipus computades
  • Definir instancies de mètodes i tipus de mètodes
  • Proporcionar nous incialitzadors
  • Definir subscripts
  • Definir i utilitzar tipus niats (“anidats”)
  • Convertir un tipus existent a un protocol

Les extensions poden estendre un tipus per i fer que adopti un o més protocols. En cas de voler indicar diversos protocols, la sintaxi seria la següent:

extension SomeType: SomeProtocol, AnotherProtocol {
    // implementation of protocol requirements goes here
}

 Nota: Si es deifineix una extensió per afegir una nova funcionalitat a un type existent, la nvoa funcionalitat estarà disponible per totes les intàncies d’aquell type, tot i qeu hagin estat prèviament creades.

Computed instance properties
modifica

Les extensions poden afegir propietats computed instance i propietats computed type a tipus existents. En aquest exemple s’afegeixen 5 propietats computed instance al tipus Double, per tal d’afegir suport per treballar amb unitats de distancia.

extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// prints "Three feet is 0.914399970739201 meters"
Incialitzadors
modifica

Permeten estendre altres tipus els teus propis tipus com a paràmetres d’inicialització a acceptar les pròpies inicialitzacions o afegir inicialitzacions diferents. Es poden afegir nous incialitzadors a una classe, però mai es pot “sobreescriure” l’inicialitzador o el desinialitazdor per defecte de la classe.ç

extension Rect {
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}
Mètodes:
modifica
extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
	    }}}
	    
//Result

3.repetitions({
    print("Hello!")
})
// Hello!
// Hello!
// Hello!

El mètode repetitions(_:) agafa un argument de tipus void (sense paràmetres) i que tampoc retorna cap valor. Després d’afegir aquest mètode es pot cridar repetitions(_:)a qualsevol integer perquè faci una tasca n vegades.

Mutació o modificació de mètodes instance
modifica

Els mètodes afegits amb una extensió poden modificar. Les estructures i mètodes d’enumeració que modifiquen self o les seves propietats han de marcar la instància com a mutating, tal i com fan els , mètodes mutating a la implementació original

El següent exemple afegeix una mutació anomenada square al tipus int que calcula el quadrat del valor original.

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()
// someInt is now 9
Subscripts
modifica

Les extensions poden afegir nous subscripts a un tipus existent.

POSAR EXEMPLE?????


Tipus niats (“anidats”)
modifica

Les extensions poden afegir tipus niats a les classes, estructures i enumeracions diferents.

extension Int {
    enum Kind {
        case Negative, Zero, Positive
    }
    var kind: Kind {
        switch self {
            case 0:
                return .Zero
            case let x where x > 0:
                return .Positive
            default:
                return .Negative
        }}}

Herència Java

modifica

En Java, la classe que deriva d’una altra classe és amoneda subclass o classe filla, mentre que la original és amoneda superclass o classe pare.

A diferencia de Swift, si es vol modificar el comportament de la classe pare, s’ha de crear una subclass que derivi de la classe pare. D’aquesta forma es poden utilitzar els camps i mètodes (a excepció de la constructora i desctructora) de la classe pare, fent una especialització concreta.


Exemple d’herència

Clase pare
modifica
public class Bicycle {
        
    // the Bicycle class has three fields
    public int cadence;
    public int gear;
    public int speed;
        
    // the Bicycle class has one constructor
    public Bicycle(int startCadence, int startSpeed, int startGear) {
        gear = startGear;
        cadence = startCadence;
        speed = startSpeed;
    }
        
    // the Bicycle class has four methods
    public void setCadence(int newValue) {
        cadence = newValue;
    }
        
    public void setGear(int newValue) {
        gear = newValue;
    }
        
    public void applyBrake(int decrement) {
        speed -= decrement;
    }
        
    public void speedUp(int increment) {
        speed += increment;
    }
        
}
Classe filla
modifica
public class MountainBike extends Bicycle {
        
    // the MountainBike subclass adds one field
    public int seatHeight;

    // the MountainBike subclass has one constructor
    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   
        
    // the MountainBike subclass adds one method
    public void setHeight(int newValue) {
        seatHeight = newValue;
    }   
}

El que et permet fer una subclass és heretar els membres i mètodes de la classe pare, reemplaçar-los i/o complimentar-los.

Atributs o Anotacions

modifica

Les anotacions són metadata d’un programa que no tenen cap efecte directa o operen sobre el codi, només serveixen per fer anotacions. Els seus possible susos sóns els següents:

Funcions

modifica
  • Informar al compilador: Les anotacions poden ser utilitzades pel compilador per detectar errors o evitar warnings.
  • Compile-time and deployment-time processin: Les eines software poden processar la informació de les anotacions per generar codi, com per exemple fitxers XML.
  • Processament en temps d’execució: Algunes anotacions permeten ser utilitzades en temps d’execució.

Per especificar una anotació, s’ha de posar el caràcter ‘@’. Això indica al compilador que és una anotació. Les anotacions poden incloure elements, que poden tenir nom o no, i els seus corresponents valors:

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
)
class MyClass() { ... }

Les anotacions es poden utilitzar en les declaracions de classes, camps, mètodes i altres elements dels programes. Des de  la versió de Java SE 8 les anotacions també poden ser aplicades a l’ús de tipus. A continuació alguns exemples:

//Class instance creation expression:
new @Interned MyObject();

//Type cast:
myString = (@NonNull String) str;
implements clause:
class UnmodifiableList<T> implements
        @Readonly List<@Readonly T> { ... }

//Thrown exception declaration:
void monitorTemperature() throws
        @Critical TemperatureException { ... }

Exemples d'anotacions

modifica
Annotació Ús
@Deprecated Indica que l’element està desfasat i que no s’hauria d’utilitzar. El compilador genera un warning quan s’utilitza el mètode marcat.
@Override Informa al compilador que l’element sobreescriurà l’element declarat a la superclass.
@SuppressWarnings Indica al compilador que no mostri alguns warnings específics que poden ser generats, com per exemple al utilitzar un mètode deprecated.
@SafeVarargs Quan s’aplica a un mètode o constructor, assegura que el codi no farà cap operació insegura en els vargargs que passa com a paràmetre. Quan s’utilitza aquesta anotació, no es mostren els warnings que estan relacionats amb els varargs.
Anotacions que s’apliquen a altres anotacions. Les més interessants són:
@Documented Indica que en els elements que s’utilitzi l’anotació seran documentats utilitzant l’eina Javadoc tool
@Target Restringeix quins tipus d’elements s’aplica l’anotació.

 

Annotació Ús
Autoclosure???? S’utilitza per retardar l’avaluació embolcallant l’expressió sense arguments. Si s’aplica aquet atribut a la declaració d’una funció o mètode que ni té arguments i retorna el tipus de l’expressió?????

La declarció d’autoclosure impkica noescape, excepte quan es passa l’atribut opcional escaping.

Available Aquest atribut s’aplica a qualsevol declaració per indicar el cicle de vida relatiu a certes plataformes i versions de sistema operatiu.

Es pot indicar com una llista, de dos o més arguments separats per coma o bé utilitzar l’asterisc (*) oer indicar que està  disponible per totes les plataformes que es llisten a continuació.

  • iOS
  • iOSApplicationExtension
  • OSX
  • OSXApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
Unavailable La declaració no està disponible per les plataforma especificades
Introduced indica a partir de quina versió de la plataforma especificada la declaració va ser introduïda
Deprecated indica la primera versió de la plataforma especificada en que la declaració està desfasada.
Deprecated indica la primera versió de la plataforma especificada en que la declaració està desfasada.
Obsoleted Indica la primera versió de la plataforma especificada en que la declaració és obsoleta. Quan una declaració és obsoleta s’elimina de la plataforma i ja no pot ser utilitzada.
Message Servei per mostrar un missatge textual que es mostra al fer la compilació o per alertar d’un error de l’ús d’una declaració que està obsoleta o desfasada. El missatge és un string.
renamed S’utilitza per mostrar un missatge textual que indica el nou nom d’una declaración que ha estat renombrada. El nou nom es mostra al compilador quan s’emet un error per el canvi de nom de la declaració. El nou nom es un string.
NS?
testable???? Apply this attribute to import declarations for modules compiled with testing enabled to access any entities marked with the internal access level modifier as if they were declared with the public access level modifier.
warn_unused_result S'utilitza perque el compilador emeti un warning quan el mètode o funció és cridat sense utilitzar el seu resultat.

No s'ha pogut entendre (error de sintaxi): {\displaystyle https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html#//apple_ref/doc/uid/TP40014097-CH35-ID347}

Garbage collector

modifica

ARC (Automatic Reference Counting)

modifica

Swift utilitza un mecanisme automàtic anomenat (ARC) que fa un seguiment i gestiona l´ús de memòria de l’aplicació. En la majoria dels casos, no cal preocupar-se per la gestió de memòria, doncs l’ARC la allibera automàticament la memòria utilitzada per una instància d’una classe quan ja no es necessita.

De totes formes, en alguns casos l’ARC necessita informació sobre la relació entre diferents parts del teu codi, per tal de poder fer la gestió automàticament. A continuació es descriuen aquests casos i es mostra com habilitar l’ARC perquè faci la gestió automàtica.

Nota: Les referencies de conteig només s’apliquen a les classees. Les estructures i les enumeracions són de tipus valor i no tipus referencia, i no son emmagatzemades i passades per referencia. 

Funcionament de l’ARC

modifica

Quan es crea una nova instancia duna classe l’ARC reserva un chunk de memòria per emmagatzemar ,aquesta instància. Aquest espai de moria guarda informació sobre el tipus d’instància i els valors que emmagatzemen les propietats d’aquesta. En el moment en que la instància ja no es necessita, l’ARC allibera la memòria. Si s’intentés accedir a una instància que l’ARC ja ha eliminat, l’aplicació donarà error.

Perquè això no passi, es fa un seguiment de quantes propietats, constants i variables fan referencia a la instancia en qüestió, l’ARC no alliberarà l’espai utilitzat per la instancia mentre hi hagi alguna referencia cap aquella instancia.

Per aquest motiu, quan s’assigna una instancia duna classe a una propietat, constant o variable, es crea una strong reference cap aquella instancia. EL lligam es diu que és fort, degut a que mentres existeixi la referencia, la instancia no s’eliminarà.

Creació d'Strong reference
modifica

Partint d’aquesta clase

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
	}
	deinit {
        print("\(name) is being deinitialized")
    }}

Si fem:

var reference1: Person?

La variable reference1 apunta nil. Pero si fem:

reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized"

Es crea una strong reference entre reference 1 i la instancia de Person. Com que hi ha almenys una strong reference, l’ARC s’assegura que aquesta instancia de Person es mantingui en memoria. Es poden crear tantes strong reference cap a la mateixa instancia com es vulgui.

reference2 = reference1
reference3 = reference1

Mentres que la instancia de Person tingui algun strong reference, no s’eliminara excepte si fem que totes apuntin a nil.

reference3 = nil
// prints "John Appleseed is being deinitialized"

Finalment s’eliminaria l'strong reference.

 
exemple strong reference
Strong Reference Cycles entre Class Instances
modifica

En els exemples anterior l’ARC és capaç de fer un seguiment del nombre de referencies de la instancia Person, però és possible escriure un codi en el que una instancia d’una class mai arribi a tenir zero referencies. Això pot passar quan dues instancies de classes tenen una strong reference entre elles, de mode que es mantenen vives mútuament. Aquest fet es coneix com a strong reference cycle.

 
Exemple strong reference cycle

L’Strong reference cycle es pot resoldre declarant les referencies com a weak or unowned en comptes d’strong references.

Weak References
modifica

S’ha d’utilitzar aquest tipus de referencia per evitar els reference cycles sempre que sigui possible que hi hagi una referencia sense valor en algun moment de la vida de l’objecte.

 
exemple weak reference
 
exmple eliminacio strong reference amb weak reference
 
exmple eliminacio weak reference
Unowned reference
modifica

Les unowned references no creen un strong hold a la instancia que es refereixen, però s’assumeix que sempre tindrà un valor, i per tant no es un tipus opcional.

 
exemple unowned reference
 
exemple eliminació unowned reference