2011-10-03 4 views
10

Sto sviluppando un'applicazione iOS con l'SDK iOS 5, il conteggio di riferimento automatico è abilitato. Ma ho un oggetto specifico che viene creato in grandi numeri e deve essere rilasciato dopo un secondo, perché altrimenti il ​​dispositivo diventerà molto lento. Sembra che non vengano rilasciati, in quanto il dispositivo è molto lento. C'è un modo per rilasciare manualmente un oggetto quando ARC è abilitato?iOS: come rimuovere oggetti dalla memoria con ARC abilitato?

MODIFICA: Il mio codice, questo è chiamato 200 volte al secondo per generare scintille. Si dissolvono dopo 0,8 secondi, quindi sono inutili dopo di allora.

int xanimationdiff = arc4random() % 30; 
    int yanimationdiff = arc4random() % 30; 
    if (arc4random()%2 == 0) { 
     xanimationdiff = xanimationdiff * -1; 
    } 
    if (arc4random()%2 == 0) { 
     yanimationdiff = yanimationdiff * -1; 
    } 

    Sparkle *newSparkle = [[Sparkle alloc] initWithFrame:CGRectMake(20 + arc4random() % 280, 20, 10, 10)]; 
    //[newSparkle setTransform:CGAffineTransformMakeRotation(arc4random() * (M_PI * 360/180))]; //Rotatie instellen (was niet mooi, net sneeuw) 
    [self.view addSubview:newSparkle]; 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.8]; 
    [newSparkle setFrame:CGRectMake(newSparkle.frame.origin.x - xanimationdiff, newSparkle.frame.origin.y - yanimationdiff, newSparkle.frame.size.width, newSparkle.frame.size.height)]; 
    newSparkle.alpha = 0; 
    [UIView commitAnimations]; 

Il codice oggetto scintilla:

#import "Sparkle.h" 

@implementation Sparkle 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"sparkle.png"]]]; 
    } 
    return self; 
} 

@end 

risposta

3

Con ARC si non può chiamaredealloc, release o retain, anche se è ancora possibile trattenere e rilasciare oggetti CoreFoundation (NB: è possibile implementare dealloc metodi per le proprie sottoclassi personalizzate, ma non è possibile chiamare super dealloc). Quindi la risposta semplice è 'no', sfortunatamente non puoi rilasciare manualmente un oggetto quando usi ARC.

Vorrei controllare che non siano stati rilasciati, perché in teoria se non si fa più riferimento a un oggetto dovrebbe essere rilasciato. Cosa fai con questi oggetti una volta creati? Li crei semplicemente e li distruggi immediatamente?

Forse potresti postare il codice che stai usando/le dichiarazioni di proprietà - sono questi weak o strong oggetti di riferimento?

+0

Ho aggiunto il mio codice alla domanda. – icant

+0

non puoi semplicemente impostare l'oggetto su 'nil'? Sono preoccupato perché sto costruendo molti oggetti NSArray e Dictionary nel ciclo e li aggiungo nell'array globale quindi non ne ho più bisogno dopo. Come ARC rimuove gli oggetti costruiti nel ciclo? – applefreak

+1

Non è proprio così che funziona: se stai creando oggetti in un ciclo for e li aggiungi a un array globale, verranno comunque mantenuti. Non possono essere rilasciati finché non vengono * rimossi * dall'array globale (ovvero, il loro numero di ritenzione è zero). – lxt

4

Ho trovato la risposta, in realtà era veramente stupido. Non ho rimosso le scintille dalla superview. Ora tolgo loro dopo 0,8 secondi con un timer e si comporta di nuovo grande :)

+3

Grande - come puoi probabilmente immaginare, quando hai una vista aggiunta a una superview è ancora conservata, quindi quella era probabilmente la radice del tuo problema. Sono contento che sia corretto! – lxt

50
Object* myObject = [[Object alloc] init];  
myObject = nil; // poof... 

EDIT: Non è possibile controllare direttamente quando un oggetto viene rilasciato, ma si può indirettamente causare che accada. Come? Ricorda cosa fa ESATTAMENTE ARC. A differenza della convenzione di codifica umana, ARC analizza il codice e inserisce le istruzioni di rilascio QUASI CHE GLI OGGETTI POSSONO essere rilasciati. Questo libera la memoria per nuove allocazioni immediatamente, il che è fantastico/necessario. Significato, impostando un oggetto su zero, o semplicemente consentendo ad una variabile di uscire dall'ambito ... qualcosa che CAUSA UN 0 CONTINUA PARTENZA costringe ARC a piazzare le sue chiamate di rilascio lì. Deve ... perché altrimenti fuoriuscirebbe.

+2

+1 per una risposta informativa e comprensibile. – piperchester

+0

Questo non è vero in tutti i casi.Se non si attivano alcune ottimizzazioni del compilatore (in genere se non si esegue la modalità di rilascio) ARC non rilascia immediatamente oggetti. –

+0

L'impostazione su zero è in genere eseguita dopo che un oggetto è apparentemente deallocato, per evitare di puntare i puntatori. Come potrebbe l'impostazione di nil causare il rilascio che alla fine causerà il dealloc? Sembra un'inversione di causa ed effetto. –

5

Basta circondare la sezione di codice che verrà chiamata 200 volte con un'istruzione @autoreleasepool {...}. Ciò causerà la deallocazione immediata della memoria anziché attendere che il controllo esegua il backup della catena di eventi fino al pool di autorelease di primo livello.