Есть ли разница между" переменной экземпляра "и" свойством " в Objective-c?


есть ли разница между" переменной экземпляра "и" свойством " в Objective-c?

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

5 77

5 ответов:

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

@interface Person : NSObject {
    NSString *name;
}

    @property(copy) NSString *name;
    @property(copy) NSString *firstName;
    @property(copy) NSString *lastName;
@end

@implementation Person
    @synthesize name;

    - (NSString *)firstName {
        [[name componentsSeparatedByString:@" "] objectAtIndex:0];
    }
    - (NSString *)lastName {
        [[name componentsSeparatedByString:@" "] lastObject];
    }
    - (NSString *)setFirstName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
    - (NSString *)setLastName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
@end

(Примечание: приведенный выше код багги в том, что он предполагает, что имя уже существует и имеет по крайней мере два компонента (например, "Билл Гейтс", а не просто "Гейтс"). Я чувствовал, что исправление этих предположений сделает фактическую точку кода менее ясной, поэтому я просто указываю на нее здесь, чтобы никто не повторил эти ошибки невинно.)

свойство-это удобный способ реализации геттера / сеттера для некоторого значения с дополнительными полезными функциями и синтаксисом. Свойство может быть поддержано переменной экземпляра, но вы также можете определить getter/setter, чтобы сделать что-то более динамичное, например, вы можете определить свойство нижнего регистра в строке, которая динамически создает результат, а не возвращает значение некоторой переменной-члена.

вот пример:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

The @property линия определяет свойство с именем propertyName типа NSString *. Это можно получить/установить, используя следующий синтаксис:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

когда вы назначаете или читаете из myObject.propertyName вы действительно вызываете методы setter / getter на объекте.

The @synthesize строка сообщает компилятору сгенерировать эти геттеры / сеттеры для вас, используя переменную-член с тем же именем свойства для хранения значения (или otherVarName если вы используете синтаксис в комментариях).

вместе с @synthesize вы все еще можете переопределить один из геттеров/сеттеров, определив свой собственный. Соглашение об именовании для этих методов является setPropertyName: для сеттера и propertyName (или getPropertyName, не стандартный) для геттера. Другой все равно будет создан для вас.

в своем @property строка вы можете определить ряд атрибутов в parens для свойства, которое может автоматизировать такие вещи, как потокобезопасность и управление памятью. По умолчанию свойство является атомарным, что означает, что компилятор обернет @synthesized get / set звонки с соответствующими блокировками для предотвращения проблем параллелизма. Вы можете указать nonatomic атрибут, чтобы отключить это (например, на iPhone вы хотите по умолчанию большинство свойств nonatomic).

есть 3 значения атрибутов, которые управляют управлением памятью для любого @synthesized сеттеры. Первый - это retain который будет автоматически отправлять release к старым значениям свойства, и retain к новым ценностям. Это очень полезно.

второй -copy что будет делать копию любых переданных значений, а не сохранять их. Это хорошая практика, чтобы использовать copy для NSString, потому что вызывающий может передать в NSMutableString и изменить его из-под вас. copy сделает новую копию ввода, к которому только у вас есть доступ.

третий assign который назначает прямой указатель без вызова метода retain / release для старого или нового объекта.

наконец, вы также можете использовать readonly атрибут для отключения сеттер для свойства.

Я использую свойства интерфейса - где объект взаимодействует с другими объектами и переменные экземпляра-это то, что вам нужно внутри вашего класса - никто, кроме вас, не должен видеть и манипулировать ими.

по умолчанию свойство readwrite будет поддерживаться переменной экземпляра, которая снова будет автоматически синтезирована компилятором.

переменная экземпляра-это переменная, которая существует и сохраняет свое значение для жизни объекта. Память, используемая для переменных экземпляра, выделяется при первом создании объекта (через alloc) и освобождается при освобождении объекта.

Если не указано иное, синтезированная переменная экземпляра имеет то же самое имя как свойство, но с префиксом подчеркивания. Например, для свойства firstName синтезированная переменная экземпляра будет называться _firstName.

ранее люди использовали свойства публично и ivars для частного использования, но с тех пор, как несколько лет назад, вы также можете определить свойства в @implementation для использования их в частном порядке. Но я бы все равно использовал ivars, когда это возможно, так как есть меньше букв для ввода, и он работает быстрее в соответствии с в этой статье. Это имеет смысл, поскольку свойства должны быть "тяжелыми": они должны быть доступны либо из сгенерированных геттеров/сеттеров, либо из тех, которые написаны вручную.

, в последних кодах от Apple, ivars больше не используются. Я думаю, потому что это больше похоже objc, а не C/C++, плюс это проще использовать свойства с assign,nullable и т. д.