Objective-C Language
속성
수색…
통사론
- @property ( optional_attributes, ... ) 유형 식별자 .
- @ syntheses identifier = optional_backing_ivar ;
- @ 동적 식별자 .
매개 변수
속성 | 기술 |
---|---|
atomic | 절대적인. 합성 된 접근 자 메서드에서 동기화를 활성화합니다. |
nonatomic | 합성 된 접근 자 메서드에서 동기화를 비활성화합니다. |
readwrite | 절대적인. getter, setter 및 backing ivar를 합성합니다. |
readonly | 직접적으로 할당 할 수있는 getter 메서드와 backing ivar 만 합성합니다. |
getter= name | getter 메서드의 이름을 지정합니다. 암시 적은 propertyName 입니다. |
setter= 이름 | setter 메소드의 이름을 지정합니다. implicity는 setPropertyName: 입니다. 콜론 : 이름의 일부 여야합니다. |
strong | ARC 하의 객체에 대해 암시 적입니다 . 뒷받침 ivar은 참조 된 객체의 할당 해제를 방지하는 __strong 사용하여 합성됩니다. |
retain | strong 동의어. |
copy | strong 같지만 합성 된 setter는 새로운 값을 -copy 라고 부릅니다. |
unsafe_unretained | ARC 하의 오브젝트를 제외하고 함축적입니다. 뒷받침 ivar은 __unsafe_unretained 사용하여 합성 __unsafe_unretained , obejcts의 경우 참조 된 객체가 할당 해제되면 포인터가 매달려있게됩니다. |
assign | unsafe_unretained 동의어입니다. 비 객체 유형에 적합합니다. |
weak | Backing ivar는 __weak 사용하여 합성되므로 참조 된 객체가 할당 해제되면 값이 무효화됩니다. |
class | 속성 접근자는 인스턴스 메서드 대신 클래스 메서드로 합성됩니다. 배킹 스토리지가 합성되지 않습니다. |
nullable | 이 속성은 nil 값을 허용합니다. 주로 스위프트 브리징에 사용됩니다. |
nonnull | 이 속성은 nil 값을 허용하지 않습니다. 주로 스위프트 브리징에 사용됩니다. |
null_resettable | 이 속성은 setter에서 nil 값을 허용하지만 getter에서 nil 값을 반환 nil 않습니다. getter 또는 setter를 사용자 정의 구현하면이 동작을 보장해야합니다. 주로 스위프트 브리징에 사용됩니다. |
null_unspecified | 절대적인. 이 속성은 nil 값의 처리를 지정하지 않습니다. 주로 스위프트 브리징에 사용됩니다. |
속성이란 무엇입니까?
다음은 속성을 사용하지 않고 두 개의 인스턴스 변수가있는 예제 클래스입니다.
@interface TestClass : NSObject {
NSString *_someString;
int _someInt;
}
-(NSString *)someString;
-(void)setSomeString:(NSString *)newString;
-(int)someInt;
-(void)setSomeInt:(NSString *)newInt;
@end
@implementation TestClass
-(NSString *)someString {
return _someString;
}
-(void)setSomeString:(NSString *)newString {
_someString = newString;
}
-(int)someInt {
return _someInt;
}
-(void)setSomeInt:(int)newInt {
_someInt = newInt;
}
@end
이것은 단순한 인스턴스 변수를 생성하는 보편적 인 코드입니다. 인스턴스 변수를 생성하고 인스턴스 변수를 설정하거나 반환하는 것 외에는 아무 작업도 수행하지 않는 접근 자 메서드를 만들어야합니다. 따라서 Objective-C 2.0에서 Apple은 상용구 코드의 일부 또는 전부를 자동으로 생성하는 속성을 도입했습니다.
다음은 위의 클래스를 속성으로 다시 작성한 것입니다.
@interface TestClass
@property NSString *someString;
@property int someInt;
@end
@implementation testClass
@end
속성은 자동 생성 된 getter 및 setter와 쌍을 이룬 인스턴스 변수입니다. someString
이라는 속성의 경우 getter 및 setter는 각각 someString
및 setSomeString:
이라고합니다. 인스턴스 변수의 이름은 밑줄 (지금의 인스턴스 변수로 시작 프로퍼티의 이름 기본적으로이다 someString
라고 _someString
하지만 이것은로 대체 할 수 있습니다 @synthesize
지시문 @implementation
섹션 :
@synthesize someString=foo; //names the instance variable "foo"
@synthesize someString; //names it "someString"
@synthesize someString=_someString; //names it "_someString"; the default if
//there is no @synthesize directive
getters와 setter를 호출하여 속성에 액세스 할 수 있습니다.
[testObject setSomeString:@"Foo"];
NSLog(@"someInt is %d", [testObject someInt]);
점 표기법을 사용하여 액세스 할 수도 있습니다.
testObject.someString = @"Foo";
NSLog(@"someInt is %d", testObject.someInt);
사용자 정의 게터 및 설정자
디폴트의 getter 및 setter 프로퍼티을 오버라이드 (override) 할 수 있습니다.
@interface TestClass
@property NSString *someString;
@end
@implementation TestClass
// override the setter to print a message
- (void)setSomeString:(NSString *)newString {
NSLog(@"Setting someString to %@", newString);
// Make sure to access the ivar (default is the property name with a _
// at the beginning) because calling self.someString would call the same
// method again leading to an infinite recursion
_someString = newString;
}
- (void)doSomething {
// The next line will call the setSomeString: method
self.someString = @"Test";
}
@end
예를 들어 게으른 초기화를 제공하는 것이 유용 할 수 있습니다 (아직 설정되지 않은 경우 getter를 재정 의하여 초기 값을 설정합니다).
- (NSString *)someString {
if (_someString == nil) {
_someString = [self getInitialValueForSomeString];
}
return _someString;
}
getter에서 값을 계산하는 속성을 만들 수도 있습니다.
@interface Circle : NSObject
@property CGPoint origin;
@property CGFloat radius;
@property (readonly) CGFloat area;
@end
@implementation Circle
- (CGFloat)area {
return M_PI * pow(self.radius, 2);
}
@end
업데이트를 유발하는 속성
이 객체 인 Shape
에는 numberOfSides
및 sideWidth
에 의존하는 속성 image
가 있습니다. 둘 중 하나가 설정되면 image
를 다시 계산해야합니다. 그러나 재 계산은 아마도 길기 때문에 두 속성이 모두 설정된 경우 한 번만 수행하면되므로 Shape
는 두 속성을 모두 설정하고 한 번만 다시 계산할 수있는 방법을 제공합니다. 이것은 ivars 속성을 직접 설정하여 수행됩니다.
Shape.h
@interface Shape {
NSUInteger numberOfSides;
CGFloat sideWidth;
UIImage * image;
}
// Initializer that takes initial values for the properties.
- (instancetype)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width;
// Method that allows to set both properties in once call.
// This is useful if setting these properties has expensive side-effects.
// Using a method to set both values at once allows you to have the side-
// effect executed only once.
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)width;
// Properties using default attributes.
@property NSUInteger numberOfSides;
@property CGFloat sideWidth;
// Property using explicit attributes.
@property(strong, readonly) UIImage * image;
@end
Shape.m
@implementation AnObject
// The variable name of a property that is auto-generated by the compiler
// defaults to being the property name prefixed with an underscore, for
// example "_propertyName". You can change this default variable name using
// the following statement:
// @synthesize propertyName = customVariableName;
- (id)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width {
if ((self = [self init])) {
[self setNumberOfSides:numberOfSides andWidth:width];
}
return self;
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides {
_numberOfSides = numberOfSides;
[self updateImage];
}
- (void)setSideWidth:(CGFloat)sideWidth {
_sideWidth = sideWidth;
[self updateImage];
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)sideWidth {
_numberOfSides = numberOfSides;
_sideWidth = sideWidth;
[self updateImage];
}
// Method that does some post-processing once either of the properties has
// been updated.
- (void)updateImage {
...
}
@end
속성을 ( object.property = value
사용하여) 할당하면 setter 메서드 setProperty:
가 호출됩니다. 이 설정자는 @synthesize
에 의해 제공 되더라도 numberOfSides
와 sideWidth
경우와 같이 무시 될 수 있습니다. 그러나 객체의 자체 또는 object->property
property
경우 property
통해 직접 ivar 속성을 설정하면 getter 또는 setter가 호출되지 않으므로 하나의 업데이트 만 호출하는 여러 속성 집합이나 세터에 의한 바이 패스 부작용.