iOS: как удалить объект из памяти с включенной ARC? - PullRequest
10 голосов
/ 03 октября 2011

Я разрабатываю приложение для iOS с iOS 5 SDK, автоматический подсчет ссылок включен.Но у меня есть конкретный объект, который создается в большом количестве и должен быть выпущен через секунду, потому что в противном случае устройство станет очень медленным.Похоже, они не выпускаются, так как устройство очень медленное.Есть ли способ освободить объект вручную, когда включен ARC?

РЕДАКТИРОВАТЬ: Мой код, это вызывается 200 раз в секунду, чтобы генерировать блестки.Они исчезают через 0,8 секунды, поэтому после этого становятся бесполезными.

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

Код объекта «Искорка»:

#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

Ответы [ 4 ]

50 голосов
/ 21 июня 2012
Object* myObject = [[Object alloc] init];     
myObject = nil; // poof...

РЕДАКТИРОВАТЬ: вы не можете напрямую контролировать, когда объект выпущен, НО вы можете косвенно заставить его произойти.Как?Помните, что ARC делает ТОЧНО.В отличие от соглашения по человеческому кодированию, ARC анализирует ваш код и вставляет операторы выпуска, КАК МОЖНО, КАК ОБЪЕКТЫ могут быть освобождены.Это сразу же освобождает память для новых распределений, что является удивительным / необходимым.Это означает, что для объекта задано значение nil или просто разрешение переменной выйти из области видимости ... то, что ПРИЧИНАЕТ 0 RETAIN COUNT, заставляет ARC делать там свои вызовы освобождения.Должно ... потому что иначе протекает.

5 голосов
/ 29 марта 2013

Просто окружите фрагмент кода, который будет вызываться 200 раз, с помощью оператора @autoreleasepool {...}. Это приведет к немедленному освобождению памяти, а не к ожиданию, пока элемент управления не пройдет весь путь назад по цепочке событий до пула автоматического выпуска верхнего уровня.

4 голосов
/ 03 октября 2011

Я нашел ответ, это было действительно очень глупо.Я не убрал блестки из суперпредставления.Теперь я удаляю их через 0,8 секунды с помощью таймера, и он снова работает отлично:)

3 голосов
/ 03 октября 2011

С ARC вы не можете вызывать dealloc, release или retain, хотя вы все равно можете сохранять и освобождать объекты CoreFoundation (примечание: вы можете реализовать dealloc методы для своих собственных пользовательских подклассы, но вы не можете позвонить super dealloc). Поэтому простой ответ «нет», к сожалению, вы не можете вручную разблокировать объект при использовании ARC.

Я бы дважды проверил, что вы уверены, что они не были выпущены, потому что теоретически, если вы больше не ссылаетесь на объект, он должен быть освобожден. Что вы делаете с этими объектами после их создания? Вы просто создаете их, а затем сразу их уничтожаете?

Возможно, вы могли бы опубликовать код, который вы используете / объявления свойств - это weak или strong ссылочные объекты?

...