サーチ…


構文

  • @property( optional_attributes、...タイプ 識別子
  • @シンセシスの識別子 = optional_backing_ivar ;
  • @動的識別子

パラメーター

属性説明
atomic 暗黙。合成されたアクセサメソッドでの同期を有​​効にします。
nonatomic 合成されたアクセサメソッドの同期を無効にします。
readwrite 暗黙。 getter、setter、backing ivarを合成します。
readonly getterメソッドとバッキングivarのみを合成します。これは直接割り当てることができます。
getter= 名前 getterメソッドの名前を指定しpropertyName 。暗黙的にはpropertyNameです。
setter= 名前 setterメソッドの名前を指定しますsetPropertyName:setPropertyName: 。結腸:名前の一部でなければならない。
strong ARCの下にあるオブジェクトに暗黙のうちに 。バッキングivarは__strongを使用して合成され、参照オブジェクトの割り当て解除を防ぎます。
retain strong同義語。
copy 同じstrongが、合成されたセッターも呼び出す-copy新しい値に。
unsafe_unretained 暗黙のうちに、ARCの下のオブジェクトを除きます。バッキングivarは、 __unsafe_unretained unsafe_unretainedを__unsafe_unretained合成されます。これは、(obejctsの場合)参照されたオブジェクトの割り当てが解除されると、ぶら下がりポインタになります。
assign unsafe_unretained同義語です。非オブジェクト型に適しています。
weak バッキング__weakを使用して合成されるため、参照されたオブジェクトの割り当てが解除されると値は無効になります。
class プロパティアクセサは、インスタンスメソッドの代わりにクラスメソッドとして合成されます。バッキングストレージは合成されません。
nullable このプロパティはnil値を受け入れます。主にスウィフトブリッジングに使用されます。
nonnull このプロパティはnil値を受け入れません。主にスウィフトブリッジングに使用されます。
null_resettable このプロパティはsetterでnil値を受け取りますが、getterから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では、ボイラープレートコードの一部または全部を自動的に生成するプロパティが導入されました。

上記のクラスはプロパティで書き換えられます:

@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);

カスタムゲッターとセッター

デフォルトのプロパティgettersおよびsetterはオーバーライドできます。

@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

これは、例えば、まだ初期化されていない場合にゲッターをオーバーライドして初期値を設定することによって、遅延初期化を行うのに便利です:

- (NSString *)someString {
    if (_someString == nil) {
        _someString = [self getInitialValueForSomeString];
    }
    return _someString;
}

ゲッターでその値を計算するプロパティを作成することもできます。

@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財産持っているimageに依存numberOfSidessideWidth 。どちらか一方が設定されている場合は、 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 。しかし、プロパティのivarを直接(オブジェクトがselfまたはobject->property property場合はpropertyを介して)設定すると、getterまたはsetterが呼び出されず、1つの更新を呼び出す複数のプロパティセットやセッターによって引き起こされるバイパス副作用。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow