Проблема здесь:
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
deviceUuid = (NSString *)cfUuid;
CFRelease(cfUuid);
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
Давайте рассмотрим, что это на самом деле делает:
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
CFUUID создан (и просочился).CFStringRef создается и присваивается cfUuid.(Примечание: имя cfUuid подразумевает, что cfUuid является CFUUIDRef. Конечно, это не так; это CFStringRef.)
deviceUuid = (NSString *)cfUuid;
Тот же самый CFStringRef тип приведен и назначенdeviceUuid.Это , а не новый экземпляр NSString или CFStringRef, это просто типографский набор того же экземпляра.
CFRelease(cfUuid);
Вы освобождаете CFStringRef.Поскольку NSString указывает на тот же объект, вы также освобождаете его.
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
И здесь вы используете типизированный объект, который был выпущен ранее.
Самое простое исправление устаревшего указателяэто:
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
deviceUuid = (NSString *)cfUuid;
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
CFRelease(cfUuid);
Но этот код опасен, и вы уже знаете, почему: deviceUuid также недопустим.Но это не очевидно, так что вы можете покататься на нем позже.Кроме того, он не устраняет утечку CFUUID.
Чтобы исправить утечку CFStringRef, вы можете использовать это:
deviceUuid = (NSString *)CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
[deviceUuid autorelease]; // or release, if you don't need it in code not
// included in your post
Однако это все равно не устраняет утечку CFUUID.
CFUUIDRef cfuuid = CFUUIDCreate(NULL);
deviceUuid = (NSString *)CFUUIDCreateString(NULL, cfuuid);
CFRelease(cfuuid);
[defaults setObject:deviceUuid forKey:@"deviceUuid"];
[deviceUuid autorelease]; // or release, if you don't need it in code not
// included in your post