Управление памятью в объективе C? - PullRequest
0 голосов
/ 04 августа 2011

У меня есть два свойства NSString, оба из которых я синтезировал и доступен только для чтения, поэтому я не могу использовать метод свойства self. но я думаю, что обе пропущенные строки наиболее сохраняются. Итак, я добавил сохранить, чтобы сохранить свойства. Но я чувствую, что у меня будут утечки здесь, так как количество пропущенных объектов увеличилось. Но мои свойства сохранят эти строки без сохранения сообщения.

-(void)setValue:(NSString *)passedString1 second:(NSString *)passedString2{
     myString = [passedString1 retain];
     hisString = [passedString2 retain];
}

Допустим, у меня есть свойство для массива (переменной), объявленного как NSArray, и я передаю NSDictionary в качестве аргумента таким образом;

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"text", @"This is some text", nil];
[self setValueForArray:dict];

-(void)setValueForArray:(NSDictionary*)passedDict{
 NSArray *someArray = [NSArray arrayWithObject:passedDict];
 if(array!=someArray){
 [array release];
 array = someArray; //I dont think I should retain this property here since it is retained by someArray
 }
}

Является ли этот подход корректным для типов NSDictionary и NSArray.

Ответы [ 3 ]

2 голосов
/ 04 августа 2011

Используйте copy для строк и освободите предыдущий объект:

-(void)setValue:(NSString *)passedString1 second:(NSString *)passedString2
{
     if (myString != passedString1)
     {
         [myString release]; 
         myString = [passedString1 copy];
     }

     if (hisString != passedString2)
     {
         [hisString release];
         hisString = [passedString2 copy];
     }
}

Если вам нужно release строк, которые были переданы в качестве параметров, сделайте это в вызывающем методе после вызова setValue:

1 голос
/ 04 августа 2011

Если вы хотите, чтобы какое-либо свойство было сохранено, рекомендуется объявить свойство как сохраняемое и использовать self. Приведенный выше код подвержен утечке памяти, поскольку вы сохраняете что-то в одном методе и, вероятно, освобождаете их в другом месте. Это вызовет много хлопот, так как оба метода связаны друг с другом, но это не зависит от логики вашего приложения. (Страшно !! Вы должны помнить это, когда будете читать код позже. Или задокументировать, если вы хотите, чтобы кто-то еще посмотрел ваш код ...)

В такие моменты, когда я хочу, чтобы какая-то переменная была сохранена и все еще не хотел использовать свойство retain в заголовке, я создаю расширение и переопределяю этот атрибут, а затем использую self.

MyClass.h

@interface MyClass : NSObject
{
    SomeClass *someObject; //Example
    ...
}
@property (nonatomic) SomeClass *someObject;
...
@end

MyClass.m

@interface MyClass () //Category
@property (nonatomic, retain) SomeClass *someObject;
@end

@implementation MyClass
...
// Use self.someObject and the object will be retained.
// Release that object in dealloc.
@end

РЕДАКТИРОВАТЬ: То же самое относится и к NSString, как ваш случай. Просто замените retain на copy, так как это рекомендуется для NSString.

1 голос
/ 04 августа 2011

Да, ваши свойства (точнее, переменные экземпляра, соответствующие свойствам) сохранят переданные строки, если вы сделаете это таким образом.Однако вы также должны убедиться, что предыдущие значения высвобождаются при назначении новых значений.Например,

- (void)setValue:(NSString*)passedString1 second:(NSString*)passedString2 {
    if (passedString1 != myString) {
        [myString release];
        myString = [passedString1 retain];
    }
    if (passedString2 != hisString) {
        [hisString release];
        hisString = [passedString2 retain];
    }
}

Также убедитесь, что вы освобождаете myString и hisString в методе dealloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...