2011-10-03 20 views
10

Estoy desarrollando una aplicación de iOS con iOS 5 SDK, el recuento automático de referencias está habilitado. Pero tengo un objeto específico que está siendo creado en grandes cantidades y debe ser liberado después de un segundo porque de lo contrario el dispositivo se volverá muy lento. Parece que no se han liberado, ya que el dispositivo es muy lento. ¿Hay alguna forma de liberar manualmente un objeto cuando ARC está habilitado?iOS: ¿Cómo eliminar objetos de la memoria con ARC habilitado?

EDITAR: Mi código, esto se llama 200 veces por segundo para generar destellos. Se desvanecen después de 0,8 segundos, por lo que son inútiles después de eso.

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]; 

El código objeto chispa:

#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 

Respuesta

3

Con ARC que no puede llamardealloc, release o retain, aunque aún puede retener y soltar objetos CoreFoundation (NB: se puede implementar dealloc métodos para sus propias subclases personalizadas, pero no puede llamar al super dealloc). Entonces la respuesta simple es 'no', desafortunadamente no se puede liberar manualmente un objeto cuando se usa ARC.

Verificaría dos veces que está seguro de que no están siendo liberados, porque en teoría si ya no hace referencia a un objeto, debe ser liberado. ¿Qué haces con estos objetos una vez que los creas? ¿Simplemente los creas y luego los destruyes de inmediato?

Quizás podría publicar el código que está utilizando/las declaraciones de propiedades: ¿estos son los objetos a los que se hace referencia weak o strong?

+0

He añadido mi código a la pregunta. – icant

+0

¿no puedes simplemente configurar el objeto a 'nil'? Estoy preocupado porque estoy construyendo muchos objetos NSArray y Dictionary en el ciclo y agregándolos en una matriz global, así que no los necesito después de eso. ¿Cómo elimina ARC los objetos construidos en el ciclo? – applefreak

+1

No funciona del todo así: si crea objetos en un bucle for y los agrega a una matriz global, se conservarán. No pueden liberarse hasta que * se eliminen * de la matriz global (es decir, su recuento retenido es cero). – lxt

4

Encontré la respuesta, en realidad era realmente estúpido. No eliminé los destellos de la super visión. Ahora me quito después de 0,8 segundos con un temporizador y realiza un gran nuevo :)

+3

Excelente: como probablemente pueda adivinar, cuando se agrega una vista a una supervista, aún se retiene, por lo que esa fue probablemente la raíz de su problema. ¡Me alegra que esté arreglado! – lxt

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

EDIT: No se puede controlar directamente cuando se suelta un objeto, sino que puedo indirectamente causar que suceda. ¿Cómo? Recuerde lo que ARC hace EXACTAMENTE. A diferencia de la convención de codificación humana, ARC analiza su código e inserta declaraciones de liberación TAN PRONTO COMO SE PUEDAN lanzar OBJETOS. Esto libera la memoria para nuevas asignaciones de inmediato, lo cual es increíble/necesario. Es decir, establecer un objeto en cero, o simplemente permitir que una variable salga del alcance ... algo que CAUSA A 0 RETAIN COUNT obliga a ARC a realizar sus llamadas de liberación allí. Debe ... porque de otro modo se filtraría.

+2

+1 para una respuesta informativa y comprensible. – piperchester

+0

Esto no es cierto en todos los casos.Si no tiene activadas ciertas optimizaciones del compilador (por lo general, si no se está ejecutando en el modo de lanzamiento), ARC no lanzará objetos inmediatamente. –

+0

La configuración de nil normalmente se hace "después" de que un objeto esté supuestamente desasignado, para evitar punteros colgantes. ¿Cómo podría la configuración no causar el lanzamiento que finalmente causará el dealloc? Parece una reversión de causa y efecto. –

5

Simplemente rodee la sección del código que se llamará 200 veces con una instrucción @autoreleasepool {...}. Esto causará que la memoria se desasigne inmediatamente en lugar de esperar a que el control vaya de regreso a la cadena de eventos hasta el grupo de autorrelease de nivel superior.

Cuestiones relacionadas