Obj-C, объект с подсчетом ссылок используется после его выпуска? - PullRequest
1 голос
/ 26 марта 2012

Я получаю следующее предупреждение.

Объект с подсчетом ссылок используется после его освобождения

ARC включен для этого файла.

Я не конвертировал свое приложение для использования ARC и в настоящее время не понимаю его. Однако, на первый взгляд, я озадачен, почему у этого кода должна быть проблема (он из библиотеки), я имею в виду, что я знаю, что здесь нельзя использовать autorelease?

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    id uuid = [defaults objectForKey:@"uniqueID"];
    if (uuid)
        uniqueID = (NSString *)uuid;
    else {
        CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
        uniqueID = (__bridge NSString *)cfUuid;
        CFRelease(cfUuid);
        [defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
    }

EDIT @JohnCalsbeek, @epatel, @Chuck Спасибо, я только что попробовал это, и я получаю новое предупреждение на линии CFStringRef cfUuid, говорящее о потенциальной утечке.

Вот полный файл https://github.com/MugunthKumar/MKStoreKit/blob/master/MKSKProduct.m

Ответы [ 4 ]

2 голосов
/ 26 марта 2012

Попробуйте это, извините за мисс, понимая, ха-ха

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuid = [defaults objectForKey:@"uniqueID"];

if (uuid)
    uniqueID = [NSString stringWithString:(NSString *)uuid];
else {
    CFUUIDRef temp = CFUUIDCreate(NULL);
    CFStringRef cfUuid = CFUUIDCreateString(NULL, temp);
    uniqueID = [NSString stringWithString:(__bridge NSString*) cfUuid];
    CFRelease(cfUuid);
    CFRelease(temp);

    [defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
}
2 голосов
/ 26 марта 2012

A __bridge приведение не является передачей права собственности.uniqueID не становится ссылкой-владельцем и поэтому становится недействительным в строке с предупреждением.Вы можете либо использовать __bridge_transfer (который передает право собственности на ссылку Objective C) и удалить свой вызов CFRelease, либо изменить вызов на CFRelease, чтобы быть после вызова на -setObject:forKey:.

1 голос
/ 26 марта 2012

Вы создаете строку с CFUUIDCreateString(NULL, CFUUIDCreate(NULL).Затем вы назначаете uniqueID также для ссылки на эту строку.Затем вы отпускаете строку с CFRelease(cfUuid).Затем вы используете строку (как uniqueID) на следующей строке.Это неверно, потому что вы только что выпустили его.

1 голос
/ 26 марта 2012

Я верю, что это может быть эта линия, которая не делает то, что вы ожидаете

uniqueID = (__bridge NSString *)cfUuid;

Это простое приведение, и следующая строка на самом деле выпустит cfUuid и uniqueID (что на самом деле является одним и тем же объектом).

Так что я бы изменил порядок следующих строк на

[defaults setObject:uniqueID forKey:@"uniqueID"]; // warning here
CFRelease(cfUuid);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...