Objective-C를 처음 접하는 사람이 @property 지시문을 따르는 보유, 할당, 복사 및 누락 된 다른 사람에 대한 개요를 알려줄 수 있습니까? 그들은 무엇을하고 있으며 왜 서로를 사용하고 싶습니까?
답변
MrMage가 링크 한 기사가 더 이상 작동하지 않습니다. 그래서 Objective-C에서 (매우) 단시간 코딩으로 배운 내용은 다음과 같습니다.
비 원자 대 원자- “원자”가 기본값입니다. 항상 “비 원자”를 사용하십시오. 나는 왜 그런지 모르겠지만 내가 읽은 책에는 “원자”를 사용하는 “드물게 이유”가 있다고 말했다. (BTW : 내가 읽은 책은 BNR “iOS Programming”책입니다.)
readwrite vs. readonly- “readwrite”가 기본값입니다. @synthesize하면 getter와 setter가 모두 생성됩니다. “읽기 전용”을 사용하면 setter가 생성되지 않습니다. 객체의 인스턴스화 후에 절대 변경하고 싶지 않은 값으로 사용하십시오.
유지 대 복사 대 할당
- “할당”이 기본값입니다. @synthesize에 의해 생성 된 setter에서 값은 단순히 속성에 할당됩니다. 나는 포인터가 아닌 속성에 “할당”을 사용해야한다는 것을 이해하고 있습니다.
- 속성이 객체에 대한 포인터 인 경우 “보존”이 필요합니다. @synthesize에 의해 생성 된 setter는 객체를 유지합니다 (일명 유지 횟수 추가). 작업이 끝나면 개체를 해제해야합니다.
- 개체가 변경 가능한 경우 “복사”가 필요합니다. 이 시점에서 객체의 값이 필요하고 해당 값이 객체의 다른 소유자가 변경 한 내용을 반영하지 않게하려면이 옵션을 사용하십시오. 사본을 보유하고 있으므로 오브젝트를 완료하면 오브젝트를 해제해야합니다.
답변
@property의 속성에 대해 알기 전에 @property의 사용법을 알아야합니다.
-
@property 는 클래스가 캡슐화 할 정보를 정의하는 방법을 제공합니다. @property를 사용하여 객체 / 변수를 선언 하면 해당 객체 / 변수는 해당 클래스를 가져 오는 다른 클래스에서 액세스 할 수 있습니다.
-
헤더 파일에서 @property 를 사용하여 객체를 선언 하면 구현 파일에서 @synthesize 를 사용하여 객체 를 합성해야 합니다. 이것은 객체 KVC를 준수 합니다. 기본적으로 컴파일러는 이 객체에 대한 접근 자 메서드 를 합성 합니다.
-
접근 자 메소드는 setter 및 getter입니다.
예 : .h
@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.미디엄
@implementation XYZClass
@synthesize name;
@end
이제 컴파일러는 name에 대한 접근 자 메서드를 합성 합니다.
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method
-
@property 의 속성 목록
원자, 비 원자, 유지, 복사, 읽기 전용, 읽기 / 쓰기, 할당, 강함, getter = method, setter = method, unsafe_unretained
-
원자가 기본 동작입니다. 객체가 원자로 선언되면 스레드로부터 안전 해집니다. 스레드 안전은 한 번에 해당 클래스의 특정 인스턴스에서 하나의 스레드 만 해당 개체를 제어 할 수 있음을 의미합니다.
스레드가 getter 메소드를 수행중인 경우 다른 스레드가 해당 오브젝트에서 setter 메소드를 수행 할 수 없습니다. 느립니다.
@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
- 비원 자는 스레드 안전하지 않습니다. nonatomic 속성 속성을 사용하여 합성 된 접근자가 단순히 값을 직접 설정하거나 반환하도록 지정할 수 있습니다. 동일한 값이 다른 스레드에서 동시에 액세스 될 경우 어떤 일이 발생하는지에 대한 보장은 없습니다.
이러한 이유로 원자 이외의 특성에 액세스하는 것이 더 빠릅니다.
@property (nonatomic)NSString *name;
- 속성이 객체에 대한 포인터 인 경우 유지 가 필요합니다.
setter 메소드는 오브젝트의 보유 횟수를 증가시켜 자동 릴리스 풀에서 메모리를 차지합니다.
@property (retain)NSString *name;
- copy copy 를 사용하면 retain을 사용할 수 없습니다. 클래스의 사본 인스턴스를 사용하면 자체 사본이 포함됩니다.
변경 가능한 문자열이 설정되고 이후에 변경 되더라도 인스턴스는 설정 당시의 값을 캡처합니다. setter 및 getter 메소드는 합성되지 않습니다.
@property (copy) NSString *name;
지금,
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
이름 은 영향을받지 않습니다.
- readonly setter 메서드를 통해 속성을 변경하지 않으려면 속성을 읽기 전용으로 선언 할 수 있습니다.
컴파일러는 getter를 생성하지만 setter는 생성하지 않습니다.
@property (readonly) NSString *name;
- readwrite 가 기본 동작입니다. readwrite 속성을 명시 적으로 지정할 필요는 없습니다.
읽기 전용과 반대입니다.
@property (readwrite) NSString *name;
- assign 은 값을 복사 또는 유지하지 않고 인스턴스 변수에 직접 할당하는 setter를 생성합니다. 이것은 NSInteger 및 CGFloat와 같은 기본 유형 또는 대리자와 같이 직접 소유하지 않은 객체에 가장 적합합니다.
가비지 수집이 활성화 된 경우 유지 및 할당은 기본적으로 호환됩니다.
@property (assign) NSInteger year;
- strong 은 보유를 대체합니다.
ARC와 함께 제공됩니다.
@property (nonatomic, strong) AVPlayer *player;
- getter = method getter 메소드 에 다른 이름을 사용하려는 경우 속성에 속성을 추가하여 사용자 정의 이름을 지정할 수 있습니다.
부울 속성 (YES 또는 NO 값이있는 속성)의 경우 getter 메서드가 “is”라는 단어로 시작하는 것이 일반적입니다.
@property (getter=isFinished) BOOL finished;
- setter = method setter 메소드 에 다른 이름을 사용하려는 경우 속성에 속성을 추가하여 사용자 정의 이름을 지정할 수 있습니다.
메소드는 콜론으로 끝나야합니다.
@property(setter = boolBool:) BOOL finished;
- unsafe_unretained Cocoa 및 Cocoa Touch에는 아직 약한 참조를 지원하지 않는 몇 가지 클래스가 있습니다. 즉, 약한 속성이나 약한 로컬 변수를 선언하여 추적 할 수 없습니다. 이러한 클래스에는 NSTextView, NSFont 및 NSColorSpace 등이 포함됩니다. 이러한 클래스 중 하나에 대한 약한 참조를 사용해야하는 경우 안전하지 않은 참조를 사용해야합니다.
안전하지 않은 참조는 관련 개체를 유지하지 않는다는 점에서 약한 참조와 비슷하지만 대상 개체의 할당이 해제되면 nil 로 설정되지 않습니다 .
@property (unsafe_unretained) NSObject *unsafeProperty;
여러 속성을 지정해야하는 경우 다음과 같이 속성을 쉼표로 구분 된 목록으로 포함하십시오.
@property (readonly, getter=isFinished) BOOL finished;
답변
많은 기사를 읽은 후 모든 속성 정보를 하나로 묶기로 결정했습니다.
- 원자 // 기본
- 비 원자
- strong = 보유 // 기본
- 약한 = unsafe_unretained
- 유지
- // 디폴트 할당
- unsafe_unretained
- 부
- 읽기 전용
- readwrite // 기본
다음은 이러한 속성을 찾을 수있는 자세한 기사에 대한 링크입니다.
최고의 답변을 주신 모든 분들께 감사드립니다 !!
다음은 기사의 샘플 설명입니다.
- atomic
-Atomic은 하나의 스레드 만 변수 (정적 유형)에 액세스 함을 의미합니다. 원자는 스레드 안전합니다. -하지만 성능이 느립니다-원자가 기본 동작입니다-가비지 수집 환경에서 (예 : 유지 / 릴리스 / 자동 릴리스를 사용하는 경우) 원자 접근자는 다른 스레드가 올바른 설정 / 가져 오기를 방해하지 않도록 잠금을 사용합니다. 가치의. -실제로는 키워드가 아닙니다.
예 :
@property (retain) NSString *name;
@synthesize name;
- nonatomic
-Nonatomic은 다중 스레드가 변수 (동적 유형)에 액세스 함을 의미합니다. -Nonatomic은 안전하지 않습니다. -하지만 성능이 빠릅니다. -Nonatomic은 기본 동작이 아니므로 속성 속성에 비 원자 키워드를 추가해야합니다. -두 개의 다른 프로세스 (스레드)가 동일한 변수에 동시에 액세스 할 때 예기치 않은 동작이 발생할 수 있습니다.
예:
@property (nonatomic, retain) NSString *name;
@synthesize name;
설명:
“name”이라는 원자 문자열 특성이 있고 스레드 A에서 [self setName : @ “A”]를 호출하는 경우 스레드 B에서 [self setName : @ “B”]를 호출하고 다음에서 [self name]을 호출하십시오. 스레드 C의 경우 다른 스레드의 모든 작업이 순차적으로 수행되므로 한 스레드가 setter 또는 getter를 실행하면 다른 스레드가 대기합니다. 이로 인해 “name”속성이 읽기 / 쓰기에 안전하지만 다른 스레드 D가 [name release]을 (를) 동시에 호출하면 여기에 관련된 setter / getter 호출이 없기 때문에이 작업으로 인해 충돌이 발생할 수 있습니다. 이는 다른 스레드가 동시에 모든 유형의 메시지를 개체에 보낼 수 있으므로 개체가 읽기 / 쓰기 안전 (ATOMIC)이지만 스레드 안전하지 않음을 의미합니다. 개발자는 그러한 물체에 대해 스레드 안전을 보장해야합니다.
“name”속성이 원자가 아닌 경우 위의 예-A, B, C 및 D에있는 모든 스레드가 동시에 실행되어 예기치 않은 결과가 생성됩니다. 원자의 경우 A, B 또는 C 중 하나가 먼저 실행되지만 D는 여전히 병렬로 실행될 수 있습니다.
- strong (iOS4 = retain)- “더 이상 가리 키지 않을 때까지 힙에 보관하십시오”-다시 말해서 “소유자입니다. 유지와 동일하게 조준하기 전에이를 해제 할 수 없습니다”- 개체를 유지해야하는 경우에만 강력하게 사용하십시오. -기본적으로 모든 인스턴스 변수와 로컬 변수는 강력한 포인터입니다. -우리는 일반적으로 UIViewControllers (UI 항목의 부모)에 강력 함을 사용합니다 -strong은 ARC와 함께 사용되며 기본적으로 객체의 보유 수에 대해 걱정할 필요가 없으므로 도움이됩니다. ARC를 사용하면 ARC가 자동으로이를 해제합니다. strong 키워드를 사용하면 객체를 소유하고 있음을 의미합니다.
예:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
- weak (iOS4 = unsafe_unretained)- “다른 사람이 강력하게 지적하는 한 이것을 유지하십시오”– 할당, 유지 또는 해제와 같은 것- “약한”참조는 유지하지 않는 참조입니다. -우리는 일반적으로 IBOutlets (UIViewController의 Childs)에 약한 것을 사용합니다. 이것은 자식 개체가 부모 개체가있는 한 존재해야하기 때문에 작동합니다. -약한 참조는 가비지 수집기에서 수집 된 개체로부터 참조 된 개체를 보호하지 않는 참조입니다. -약한 것은 기본적으로 유지되지 않은 속성입니다. 객체가 할당 해제 될 때를 제외하고 약한 포인터는 자동으로 nil로 설정됩니다.
예 :
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
BJ 호머 덕분에 강력하고 약한 설명 :
우리의 물건이 개이고, 개가 도망 치고 싶다고 상상해보십시오. 강한 포인터는 강아지의 가죽 끈과 같습니다. 가죽 끈이 개에 붙어있는 한 개는 도망 가지 않습니다. 5 명이 가죽 끈을 1 마리의 개 (한 물체에 5 개의 강한 포인터)에 부착하면 5 개의 가죽 끈이 모두 분리 될 때까지 개가 도망 가지 않습니다. 반면에, 약한 포인터는 어린 아이들이 개를 가리키며 “보라! 개”라고 말하는 것과 같습니다. 개가 여전히 가죽 끈에있는 한, 작은 아이들은 여전히 개를 볼 수 있으며, 여전히 개를 가리킬 것입니다. 그러나 모든 가죽 끈이 분리 되 자마자, 작은 아이가 몇 개를 가리켜도 개는 도망칩니다. 마지막 강한 포인터 (끈)가 더 이상 객체를 가리 키지 않으면 객체가 할당 해제되고 모든 약한 포인터는 0이됩니다. 우리가 약한 것을 사용할 때? 당신이 약한 것을 사용하고 싶은 유일한 시간은 당신이 유지주기를 피하고 싶을 때입니다.
- retain = strong-이 유지되고 이전 값이 해제되고 할당됩니다 -retain 새 값을 보내도록 지정합니다.-지정시 유지하고 이전 값을 보냅니다. -release -retain은 strong과 같습니다. -apple은 작성하면 작성하면 자동으로 변환 / 강하게 작동합니다. “alloc”과 같은 방법에는 암시 적 “보유”가 포함됩니다.
예:
@property (nonatomic, retain) NSString *name;
@synthesize name;
- assign
-assign이 기본값이며 단순히 변수 할당을 수행합니다. -assign은 컴파일러에게 속성의 setter 구현을 합성하는 방법을 알려주는 속성 특성입니다.-C 프리미티브 속성에 assign을 사용하고 Objective-C 객체에 대한 약한 참조에는 약합니다.
예:
@property (nonatomic, assign) NSString *address;
@synthesize address;
-
unsafe_unretained
-unsafe_unretained는 보유 / 릴리스 호출을 삽입하는 방법을 ARC에 알려주는 소유권 한정자입니다. -unsafe_unretained는 assign의 ARC 버전입니다.
예:
@property (nonatomic, unsafe_unretained) NSString *nickName;
@synthesize nickName;
- 부
객체가 변경 가능한 경우 -copy가 필요합니다. -copy는 할당시 새 값을 보내도록 지정하고 이전 값을 보내면 해제됩니다. -copy is retain은 비가 비지 수집 환경에서 명시 적으로 해제 (예 : 할당 해제)해야하는 객체를 반환합니다. -복사를 사용하는 경우 여전히 할당을 해제해야합니다. -현재 객체의 값이 필요하고 객체의 다른 소유자가 변경 한 값을 반영하지 않으려면이 값을 사용하십시오. 사본을 보유하고 있으므로 오브젝트를 완료하면 오브젝트를 해제해야합니다.
예:
@property (nonatomic, copy) NSArray *myArray;
@synthesize myArray;
답변
한 번에 하나의 스레드 만 원자 속성에 액세스 할 수 있습니다. 그것은는 스레드 안전합니다 . 기본값은 atomic입니다. 키워드 atomic 이 없습니다.
비원 자란 다중 스레드가 항목에 액세스 할 수 있음을 의미합니다. 스레드 안전하지 않은
따라서 atomic을 사용하는 동안 매우 조심해야합니다.
답변
iOS의 objective-c 속성에 대한이 링크를 선호합니다.
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html