Domanda

Nota:. Sono relativamente nuovo per Objective-C e vengo da Java e PHP

Qualcuno potrebbe spiegarmi perché devo sempre prima assegnare e poi inizializzare un esempio?

Non potrebbe questo essere fatto nei metodi init in questo modo:

+ (MyClass*)init {
    MyClass *instance = [MyClass alloc];
    [instance setFoo:@"bla"];

    return instance;
}

+ (MyClass*)initWithString:(NSString*)text {
    MyClass *instance = [MyClass init];
    [instance setFoo:text];

    return instance;
}
...

E 'solo un relitto dei vecchi tempi C o c'è qualcosa che non sto vedendo?

So che questo non è un problema come ho potuto così sempre chiamare alloc e init, ma dal momento che è un po 'noioso mi piacerebbe almeno sapere perché lo sto facendo.

I sta piacendo l'espressività del linguaggio fino ad ora, ma questo è qualcosa che voglio comprendere appieno per pensare il modo in Objective-C.

Grazie!

È stato utile?

Soluzione

+ nuovo finisce per l'invio di un messaggio di + alloc alla classe e un messaggio -init a tutto ciò che torna da + alloc.

La ragione per cui NeXT partì dalla convenzione di Stepstone di utilizzare il + nuovo messaggio (che era un'idea Smalltalk) è che nella fase iniziale, hanno incontrato situazioni in cui volevano essere in grado di inizializzare lo stesso oggetto più di una volta.

Altri suggerimenti

Poiché la creazione di un'istanza e inizializzare un'istanza sono due processi separati.

Si invia un messaggio alloc alla classe per ottenere un'istanza non inizializzata. È quindi necessario inizializzare l'istanza, e si ha spesso diversi modi per farlo. Ad esempio:

myStr = [[NSString alloc] init]; //Empty string
myStr = [[NSString alloc] initWithFormat:@"%@.%@", parentKeyPath, key];
myStr = [[NSString alloc] initWithData:utf16data encoding:NSUnicodeStringEncoding error:&error];
myStr = [[NSString alloc] initWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:&error];

Ognuno di questi inizializza la stringa in un modo completamente diverso. Come si inizializza la stringa dipende da ciò che si desidera inizializzare da.

Naturalmente, a nessuno piace la scrittura alloc e quindi init e poi autorelease ogni volta, in modo di solito si hanno metodi di convenienza (per esempio, stringWithFormat:) che fanno tutti e tre i passaggi per voi.

Modifica: Per ulteriori informazioni su questo argomento, tra cui intuizioni essenziali di commentatori, vedi il mio post sul blog “ Riunificazione ”.

Vedere NSZone.

+alloc è un taglio scorciatoia per +allocWithZone:, che è un meccanismo Cocoa prevede ottimizzare allocazione di memoria.

Quindi, si ha la possibilità di fare qualcosa di simile a questo:

foo = [[NSString allocWithZone:MyZone] initWithString:@"Foo"];
foo2 = [foo copyWithZone:MyZone];

L'idea alla base di zone di memoria è che se si dispone di un gran numero di oggetti simili che sono frequentemente allocate e deallocato essa può più efficiente utilizzare una zona di memoria separata per tali oggetti.

Al fine di zonizzazione per essere efficace che ci si vuole avere +allocWithZone: a disposizione di ogni sottoclasse NSObject, quindi è necessario separare l'allocazione e l'inizializzazione. È possibile creare e utilizzare tutti i collegamenti che si desidera, come +new, ma sotto sotto è necessario un metodo -init che inizializza un oggetto che è già stato assegnato.

"Separazione delle fasi di allocazione e inizializzazione di creazione dell'istanza fornisce molti vantaggi. È possibile utilizzare qualsiasi variazione del procedimento + classe alloc di assegnare un'istanza e quindi utilizzare qualsiasi inizializzatore disponibili con le nuove instance.This rende possibile creare i propri metodi di inizializzazione senza la necessità di fornire implementazioni alternative di tutti i metodi di assegnazione. Nuovi metodi di allocazione sono raramente creati perché i metodi esistenti si incontrano quasi ogni tipo di esigenza. Tuttavia, uno o più nuovi inizializzatori sono creati per quasi ogni classe. Grazie alla separazione delle fasi di assegnazione e inizializzazione, implementazioni inizializzazione avere a che fare con le variabili di nuovi casi e può completamente ignorare le questioni sur- arrotondamento allocation.The separazione semplifica il processo di scrittura initializers. Inoltre, cacao inizializzatori standard come -initWithCoder: lavorano con istanze indipendentemente dalla memoria modo per l'istanza è stata assegnata. Una conseguenza negativa della separazione di allocazione e inizializzazione è la necessità di essere a conoscenza di convenzioni come il designato initializer.You deve conoscere quali metodi inizializzatori designati e come creare e documentare nuovi initializers in sottoclassi. Nel lungo periodo, utilizzando inizializzatori designati semplifica lo sviluppo di software, ma v'è un argomento da effettuare quel modello di creazione theTwo-Stage si aggiunge alla curva di apprendimento precoce per gli sviluppatori di cacao. "


(c) Patterns Cacao Design by Erik M. Buck e Donald A. Yacktman

Non è necessario. È possibile utilizzare [MyClass new]. Questo è simile al metodo init ipotetica.

Fondamentalmente, Objective-C, che non hanno garbage collection inizialmente, separa il concetto di allocazione di memoria e l'inizializzazione di classe. Ecco perché ci sono due metodi distinti. Quando si chiama alloc, si assegnano in modo esplicito la memoria.

La maggior parte delle classi hanno quello che stai chiedendo. Avete ottenuto risposte prima sul perché questo è come è e perché non sarebbe sempre desidera utilizzare questo tutto il tempo, ma se si legge la documentazione per le classi vedrete molti metodi di classe che agiscono in questo modo e sono spesso utilizzati.

Per NSString avete, per esempio:

+ (id)string  // (Empty string)
+ (id)stringWithFormat:...  // Formatted string (like you use)
+ (id)stringWithContentsOfURL:... // String populated with contents of URL

E così via. E si potrebbe quindi utilizzare questo come: NSString *myString = [NSString stringWithFormat:@"Hello %@\n", userName];

La maggior parte delle altre classi hanno questa, come NSArray:

+ (id)array
+ (id)arrayWithContentsOfFile:...
+ (id)arrayWithContentsOfURL:...
+ (id)arrayWithObjects:...

Hai solo bisogno di leggere la documentazione. :) E leggere le altre risposte sul perché non si desidera utilizzare questo troppo.

alloc : memoria viene assegnata / data all'oggetto riferimento. Ora di riferimento ha il possesso della memoria, ma non ha ancora fatto nulla. Questa memoria sia vuota (caso raro) o con alcuni dati anonimi.

alloc e init : memoria allocata viene pulito / svuotata. La memoria è iniziata da poco lo zero.

alloc e initwithdata ... :. Memoria allocata è iniziata con i dati desiderati rispettati per le proprietà della classe

Per esempio, quando si acquista una trama che si ottiene il possesso. Questo terreno è dato a voi come è, mattoni in rovina o vecchia casa può essere lì. Questo è alloc .

Quando si pulire il terreno e rimuovere tutta la sporcizia e rifiuti. Questo è alloc con init.

Quando si genera che in qualche casa di valore diventa più significativo per voi. Ed è alloc initwith ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top