Devo fare riferimento a sé.proprietà nel metodo init con l’ARCO?

Una domanda veloce.

se ho una proprietà e un ivar dichiarato con lo stesso nome:

nel .h:

(Reminder*)reminder;
@property(nonatomic,strong)(Reminder*)reminder;

nel .m file, è necessario utilizzare il ivar o la proprietà nel metodo init se sto usando l’ARCO?

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
    }
    return self;
}

O devo utilizzare la proprietà per ottenere il beneficio del sistema automatico di conteggio dei riferimenti come questo:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        self.reminder = reminder_;
    }
    return self;
}

Non so a che punto dell’oggetto di inizializzazione di proprietà diventano accessibili con la dot notation.

  • se si utilizza sintetizzare (credo che si fa) e di utilizzare un compilatore (credo che si fa, perché di ios5) non c’è bisogno di dichiarare il ivar, objective-c che fa automaticamente per voi. (questa non è la risposta alla tua domanda, solo una nota a margine).
  • Questa è una buona cosa da sapere, ho sempre dichiarato di ivars di proprietà fino ad ora. E sì, ho @sintetizzare la struttura, con il nome predefinito.
  • Stavo per dire la stessa cosa di @scelta. E credo che ancora ottenere il beneficio di ARCO indipendentemente dal fatto che o non si utilizza la proprietà.
  • Non hai nemmeno bisogno di @synthesize
InformationsquelleAutor Alex Stone | 2011-11-08



3 Replies
  1. 67

    Utilizzare l’accesso diretto in parzialmente costruita stati, indipendentemente dal ARCO:

    - (id)initWithReminder:(Reminder*)reminder_ {
        self = [super init];
        if (self) {
            reminder = reminder_;
            //OR
            reminder = [reminder_ retain];
        }
        return self;
    }

    Questo perché self.whatever attiverà altri effetti collaterali, come la Chiave-Valore Osservare (KVO) le notifiche, o forse la classe implementa (esplicitamente) o di una sottoclasse sostituisce setWhatever: — e che potrebbe esporre i propri parzialmente inizializzato esempio per altre Api (compreso il suo), che giustamente si supponga hanno a che fare con una cucina completamente costruito in oggetto.

    Si potrebbe verificare manualmente che una classe è in grado di operare in parziale stato di inizializzazione, ma che richiede un sacco di manutenzione e (francamente) impraticabile o impossibile quando la gente desidera creare una sottoclasse della classe. Essa richiede un sacco di tempo e di manutenzione, e non c’è substantiative vantaggio di farlo, soprattutto se si tenta di utilizzare il metodo di come convenzione.

    Così l’uniforme che garantisce la correttezza è quello di utilizzare l’accesso diretto in parzialmente costruito uniti, e di evitare di utilizzare le funzioni di accesso.

    Nota: sto usando “parzialmente costruito” a causa di inizializzazione è solo la metà delle foto; -dealloc ha simili problemi.

    Qualche dettaglio in più per cui si dovrebbe utilizzare l’accesso diretto in parzialmente costruita stati (ARC || MRC) può essere trovato qui: L’inizializzazione di una proprietà, la notazione con il punto

    • Io sono un po ‘ confuso da questo, quando si tratta di sottoclasse. Se non dovremmo utilizzare sé.propertyName in init metodi, come hai accesso a un genitore della classe di proprietà all’interno del metodo init di una sottoclasse ? utilizzando _propertyName nella sottoclasse dice variabile non dichiarata, l’unica soluzione è di usare auto.propertyName. Esempio: stackoverflow.com/questions/16622776/…
    • in generale, si dovrebbe evitare di accedere alle proprietà della classe base, gli inizializzatori. questo approccio richiede la classe derivata per conoscere la sua superclasse di attuazione, nonché di tutte le classi derivate che poteva ignorare la funzione di accesso implementazioni. in objc, si può effettivamente finire per chiamare (non inizializzato) classe derivata’ l’override di metodi supplementari. così si può evitare questo mal di testa/rischio: seguendo i consigli di cui sopra, fornendo più appropriato inizializzatori, utilizzando le funzioni di accesso completamente costruito istanze, utilizzando i tipi meno complessi (composizione), la convenienza, costruttori, etc.
    • Penso che sia sicuro per chiamare la proprietà dalla superclasse nella sottoclasse’ init. Con il tempo si raggiunge la “corpo” della sottoclasse’ init, superclasse’ init dovrebbe aver già finito. Che significa, stessa superclasse è (o almeno dovrebbe essere, se scritto correttamente) già completamente inizializzato. Accedendo così la sua (= superclasse’) proprietà dovrebbe essere al sicuro – anche se l’override della proprietà nella sottoclasse. Il problema è quando si accede alla proprietà in init nella superclasse. In tal caso, se si esegue l’override di setter nella sottoclasse, si può arrivare con parzialmente inizializzato l’oggetto.
    • non è molto sicuro, soprattutto perché la complessità delle gerarchie di classi e classi aumento: stackoverflow.com/questions/5932677/… — vero, si può fare una dimostrabile la progettazione sicura di ma che vuole verificare che rimane al sicuro ogni volta che le implementazioni sono modificati? è complicato/noioso/di errori e non comprare molto.
    • ok, quindi quando ho sottoclasse UITableViewCell e si desidera aggiungere aggiungere alcune personalizzato UIView come sottoview per la sua contentView in inizializzazione, cosa dovrei fare invece di: [self.contentView addSubview:someSubview]; ?
    • nel quadro più ampio, è possibile eseguire tale programma di installazione dopo tutti gli inizializzatori sono stati eseguiti e l’istanza è completamente inizializzato. forse è in un -awakeFromNib, lazy initialization, o un’altra fase di installazione — dipende dall’oggetto.
    • Se io costruisco il mio UITableViewCell sottoclasse nel codice (non si può dire che è vietato), quindi awakeFromNib non è un’opzione. Utilizzando lazy initialization in tal caso, a mio parere, semplice soluzione di un problema. Io uso lazy initialization solo quando è logico (ad esempio, quando non pigro init è il collo di bottiglia che è piuttosto NON è il caso qui) – non in ordine di attaccare a qualche altro (non abbastanza) le regole… Ma ok, penso che abbiamo solo due diversi approcci e priorità che si applicano al nostro codice 🙂
    • Ho fornito una terza, molto ampio opzione: “un’altra tappa del programma di installazione – dipende dall’oggetto”. Forse questo è il codice del client di dominio, di una sostituzione, un piccolo costruttore, le implementazioni delle proprietà, etc. – si può approcciare i problemi in molti modi in codice. Non c’è uno che si adatta ad ogni implementazione idealmente, e sicuramente troppe varianti per i campi di commento.

  2. 0

    Non so a che punto dell’oggetto di inizializzazione di proprietà diventano accessibili con la dot notation.

    Dal momento che la dot notation è ancora un Obiettivo, metodo C (e C metodo sotto l’ObjC metodo) la dot notation, o chiamando il metodo, è perfettamente sicuro DATO che il metodo è disposto a trattare con il tipo sottostante(s) in memoria in qualsiasi stato si trovino in.
    La normale regola di evitare l’uso di un uninitiatilized (forse) garage segmento di memoria sarebbe ancora applicare. Che è la più forte motivazione per l’uso di ivar in init.

    Ma se il tuo metodo (getter|setter) è in grado di correttamente utilizzando il segmento di memoria – indipendentemente dal fatto che viene scritto prima di leggere – quindi con tutti i mezzi utilizzare il getter nel metodo init.
    Un Pigro getter sfrutta l’ipotesi che un puntatore viene inizializzata inizia come ‘zero’ per decidere di eseguire l’inizializzazione. Se non è possibile assumere il contenuto iniziale della memoria, quindi l’inizializzazione di ivar potrebbe essere la via più sicura.

    Perché la regola di non utilizza mai i setter o getter in init se il metodo è in grado di funzionare correttamente in questo scenario?

Lascia un commento