Objective-C:属性

“属性”(property)是Objective-C的一项新特性,用于封装对象中的数据。有两大概念:ivar(实例变量)、(存)取方法。

@property = ivar + getter (+ setter);
// 只读属性只有getter  

property 在 runtime 中是 objc_property_t 定义如下:

typedef struct objc_property *objc_property_t;
struct property_t {
    const char * name;
    const char * attributes;
};

name 就是属性的名称,attributes 包括:类型,内存语义,原子性,和对应的实例变量,但是其实并不是这四项都会有。举个:

@property (nonatomic,copy) NSString *str;
// name:str attributes:T@"NSString",C,N,V_str
@property (atomic,assign) NSInteger num;
// name:num attributes:Tq,V_num

这里面关键的是属性的类型,对于对象类型的,可以使用isKindOfClass来判断,但是对于数据类型,就可以使用attributes中的类型来判断。列举常见一些类型:

NSInteger,long     Tq,N,V_
NSUInteger         TQ,N,V_
CGFloat,double     Td,N,V_
float              Tf,N,V_
int                Ti,N,V_
bool               TB,N,V_
CGRect T{CGRect={CGPoint=dd}{CGSize=dd}},N,V_rect
CGPoint T^{CGPoint=dd},N,V_point

完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。这个过程由编译器在编译期执行。

@property只是声明了一个属性,具体的实现有两个对应的词,

  • @synthesize:编译器自动添加 setter 方法和 getter 方法
  • @dynamic:禁止编译器自动添加 setter 方法和 getter 方法

如果 @synthesize 和 @dynamic 都没写,那么默认的就是

@syntheszie var = _var;

@syntheszie 的使用场景

手动实现了 setter 方法和 getter (或者重写了只读属性的 getter 时)

@interface Test : NSObject
@property (nonatomic,copy,readonly) NSString *name;
@property (nonatomic,assign) NSInteger age;
@end
@implementation Test
@synthesize age = _age;
@synthesize name = _name;
- (void)setAge:(NSInteger)age {
    _age = age;
}
- (NSInteger)age {
    return _age;
}
- (NSString *)name {
    return _name;
}
@end

实现在 @protocol 中定义的属性

@protocol TestProtocol 
@property (nonatomic,assign) NSInteger age;
@end

@interface Test : NSObject
@end

@implementation Test
@synthesize age = _age;
//@synthesize age; // 成员变量名称就是 age
@end

重写父类的属性时

@interface Super : NSObject
@property(nonatomic,assign) NSInteger age;
@end

@implementation Super
- (instancetype)init {
    self = [super init];
    if (self) {
        _age = 10;
    }
    return self;
}
@end

@interface Test : Super {
    NSInteger _testAge;
}
@end

@implementation Test
@synthesize age = _testAge;
- (instancetype)init{
    self = [super init];
    if (self) {
        _testAge = 20;
    }
    return self;
}
@end

你可能感兴趣的:(Objective-C:属性)