[objective-c] Objective-c에서 “인스턴스 변수”와 “속성”간에 차이가 있습니까?
Objective-c에서 “인스턴스 변수”와 “속성”사이에 차이가 있습니까?
나는 이것에 대해 잘 모르겠습니다. “속성”은 접근 자 메서드가있는 인스턴스 변수라고 생각하지만 잘못 생각할 수 있습니다.
답변
속성은 좀 더 추상적 인 개념입니다. 인스턴스 변수는 말 그대로 구조체의 슬롯과 같은 저장소 슬롯입니다. 일반적으로 다른 개체는 직접 액세스 할 수 없습니다. 반면 속성은 액세스 할 수있는 객체의 속성입니다 (모호하게 들리며 그래야합니다). 일반적으로 속성은 인스턴스 변수를 반환하거나 설정하지만 여러 데이터를 사용하거나 전혀 사용하지 않을 수 있습니다. 예를 들면 :
@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
(참고 : 위의 코드는 이름이 이미 존재하고 최소한 두 개의 구성 요소 (예 : “Gates”가 아닌 “Bill Gates”)가 있다고 가정한다는 점에서 버그가 있습니다. 이러한 가정을 수정하면 코드의 실제 포인트가 될 것이라고 생각했습니다. 덜 명확하므로 여기에서 지적하고 있으므로 아무도 이러한 실수를 순진하게 반복하지 않습니다.)
답변
속성은 유용한 기능과 구문을 추가하여 일부 값에 대해 getter / setter를 구현하는 친숙한 방법입니다. 속성은 인스턴스 변수에 의해 지원 될 수 있지만 좀 더 동적 인 작업을 수행하기 위해 getter / setter를 정의 할 수도 있습니다. 예를 들어 일부 멤버의 값을 반환하는 대신 결과를 동적으로 생성하는 문자열에 lowerCase 속성을 정의 할 수 있습니다. 변하기 쉬운.
예를 들면 다음과 같습니다.
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
이 @property
줄은 propertyName
유형 이라는 속성을 정의합니다 NSString *
. 다음 구문을 사용하여 가져 오거나 설정할 수 있습니다.
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
할당하거나 읽을 때 myObject.propertyName
실제로 개체에 대한 setter / getter 메서드를 호출합니다.
이 @synthesize
줄은 값을 저장하기 위해 속성과 동일한 이름을 가진 멤버 변수 otherVarName
를 사용하여 (또는 주석에 구문을 사용하는 경우) 이러한 getter / setter를 생성하도록 컴파일러에 지시합니다 .
함께 @synthesize
자신을 정의하여 getter / setter 중 하나를 재정의 할 수 있습니다. 이러한 메서드의 명명 규칙 setPropertyName:
은 setter 및 getter에 대한 propertyName
(또는 getPropertyName
표준이 아님)입니다. 다른 하나는 여전히 생성됩니다.
당신에 @property
선 당신은 스레드 안전성 및 메모리 관리 등을 자동화 할 수있는 속성에 대한 괄호에있는 속성의 수를 정의 할 수 있습니다. 기본적으로 속성은 원자 적입니다. 즉, 컴파일러는 @synthesiz
동시성 문제를 방지하기 위해 적절한 잠금으로 ed get / set 호출을 래핑 합니다. nonatomic
이를 비활성화 하는 속성을 지정할 수 있습니다 (예 : 대부분의 속성을 기본값으로 설정하려는 iPhone nonatomic
).
모든 @synthesized
setter에 대한 메모리 관리를 제어하는 3 개의 속성 값이 있습니다. 첫 번째는 속성의 이전 값과 새 값 retain
으로 자동으로 전송 됩니다. 이것은 매우 유용합니다.release
retain
두 번째는 copy
전달 된 값을 유지하지 않고 복사하는 것입니다. copy
호출자가 NSMutableString을 전달하고 아래에서 변경할 수 있기 때문에 NSString 을 사용 하는 것이 좋습니다 . copy
사용자 만 액세스 할 수있는 입력의 새 사본을 만듭니다.
세 번째는 assign
이전 또는 새 개체에 대해 유지 / 해제를 호출하지 않고 직선 포인터 할당을 수행하는 것입니다.
마지막으로 readonly
속성을 사용하여 속성에 대한 setter를 비활성화 할 수도 있습니다 .
답변
인터페이스 부분에 대한 속성을 사용합니다. 개체가 다른 개체 및 인스턴스 변수와 인터페이스하는 것은 클래스 내에서 필요한 것입니다.하지만 아무도보고 조작해야합니다.
답변
기본적으로 readwrite 속성은 인스턴스 변수에 의해 지원되며 컴파일러에 의해 자동으로 다시 합성됩니다.
인스턴스 변수는 존재하고 객체의 수명 동안 그 값을 보유하는 변수입니다. 인스턴스 변수에 사용되는 메모리는 객체가 처음 생성 될 때 (할당을 통해) 할당되고 객체가 할당 해제되면 해제됩니다.
달리 지정하지 않는 한 합성 된 인스턴스 변수의 이름은 속성과 동일하지만 밑줄 접두사가 있습니다. 예를 들어 firstName이라는 속성의 경우 합성 된 인스턴스 변수는 _firstName이됩니다.
답변
이전에는 사람들이 속성을 공개적으로 사용하고 ivars를 개인 용도로 사용했지만 몇 년 전부터 속성을 정의 @implementation
하여 비공개로 사용할 수도 있습니다. 그러나 입력 할 문자가 적고이 기사 에 따라 더 빠르게 실행되므로 가능하면 ivars를 계속 사용합니다 . 속성은 “무거움”을 의미하기 때문에 의미가 있습니다. 생성 된 getter / setter 또는 수동으로 작성된 것에서 액세스해야합니다.
그러나 Apple의 최근 코드에서는 ivar가 더 이상 사용되지 않습니다. 더 같이이기 때문에 추측 objc
이 아니라 C/C++
, 그것 플러스와 속성을 사용하는 것이 더 쉽습니다 assign
, nullable
등