수색…


통사론

  • @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는 각각 someStringsetSomeString: 이라고합니다. 인스턴스 변수의 이름은 밑줄 (지금의 인스턴스 변수로 시작 프로퍼티의 이름 기본적으로이다 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 에는 numberOfSidessideWidth 에 의존하는 속성 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 에 의해 제공 되더라도 numberOfSidessideWidth 경우와 같이 무시 될 수 있습니다. 그러나 객체의 자체 또는 object->property property 경우 property 통해 직접 ivar 속성을 설정하면 getter 또는 setter가 호출되지 않으므로 하나의 업데이트 만 호출하는 여러 속성 집합이나 세터에 의한 바이 패스 부작용.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow