分析Runtime的属性Property

一、介绍

在OC中我们可以给任意的一个类以@property的格式声明属性,当然对于这个属性也会采用某一些属性关键字进行修饰,那么属性的真正的面目是啥样子的呢?其实,runtime源码中可以看到,property是一个结构,如下所示,只不过苹果为这个结构体另外定义了一个结构体指针。

//属性结构体指针
typedef struct objc_property *objc_property_t;

二、函数

正如我们所知,MJExtension是一个非常流行的json解析框架,其内部对对象的每一个属性进行解析的方式其实就是通过runtime来实现的。runtime源码中提供了属性的相关API函数。通过这些函数,我们可以轻松的得到每一个属性名和类型以及特性,相关函数如下:

//获取一个属性
objc_property_t _Nullable class_getProperty(Class _Nullable cls, const char * _Nonnull name);

//添加一个属性
class_addProperty(Class _Nullable cls, const char * _Nonnull name, const objc_property_attribute_t * _Nullable attributes,unsigned int attributeCount);

//替换一个属性
class_replaceProperty(Class _Nullable cls, const char * _Nonnull name, const objc_property_attribute_t * _Nullable attributes,unsigned int attributeCount)

//获取属性数组
objc_property_t _Nonnull * _Nullable class_copyPropertyList(Class _Nullable cls, unsigned int * _Nullable outCount);

//获取属性名称
const char * _Nonnull property_getName(objc_property_t _Nonnull property) ;

//获取属性描述名称
const char * _Nullable property_getAttributes(objc_property_t _Nonnull property);

//获取属性描述数组
objc_property_attribute_t * _Nullable property_copyAttributeList(objc_property_t _Nonnull property,unsigned int * _Nullable outCount);

//通过属性描述的name获取属性描述的value
property_copyAttributeValue(objc_property_t _Nonnull property,const char * _Nonnull attributeName); 

//属性描述结构体
typedef struct {
    const char * _Nonnull name;           /**< The name of the attribute */
    const char * _Nonnull value;          /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;

三、案例

了解了基本函数后,现在来上手,获取并打印看看property到底是个啥样,代码如下:

//定义一个对象,声明各种属性property
@interface SubObject : NSObject
@property (nonatomic,   copy) NSString *name;
@property (nonatomic,   copy) void (^Block)(void);
@property (nonatomic,   weak) id<NSObject> delegate;
@property (nonatomic, assign) int      age;
@property (nonatomic, assign) float    height;
@property (nonatomic, assign) double   weight;
@property (nonatomic, strong) NSNumber *num;
@property (nonatomic, strong) NSDate   *date;
@property (nonatomic, strong) NSData   *data;
@property (nonatomic, strong) NSArray  *array;
@property (nonatomic, strong) NSDictionary *dic;
@property (nonatomic, strong) MyObject *myObject;
@end
//获取属性列表
unsigned int count;
objc_property_t *properties = class_copyPropertyList([subObject class], &count);
for (int i=0; i<count; i++) {

      //获取属性
      objc_property_t property = properties[i];

      //属性名称
      const char *propertyName = property_getName(property);
      NSLog(@"------propertyName = %s-------",propertyName);

      //属性描述名称
      const char * property_attr = property_getAttributes(property);
      NSLog(@"------property_attr = %s-------",property_attr);

      //属性类型
      const char *propertyType = property_copyAttributeValue(property, "T");
      NSLog(@"------propertyType = %s-------",propertyType);

      //属性变量名称
      const char *property_Value = property_copyAttributeValue(property, "V");
      NSLog(@"------property_Value = %s-------",property_Value);

      //属性描述列表
      unsigned int outCount;
      objc_property_attribute_t *attributeList = property_copyAttributeList(property, &outCount);
      for (int j=0; j<outCount; j++) {
          objc_property_attribute_t attribute = attributeList[j];
          NSLog(@"property_attribute_t_name:%s-----property_attribute_t_value:%s",attribute.name,attribute.value);
      }
      NSLog(@"");
}
2019-11-10 19:18:10.335830+0800 运行时[4530:256535] ------propertyName = name-------
2019-11-10 19:18:10.336009+0800 运行时[4530:256535] ------property_attr = T@"NSString",C,N,V_name-------
2019-11-10 19:18:10.336152+0800 运行时[4530:256535] ------propertyType = @"NSString"-------
2019-11-10 19:18:10.336261+0800 运行时[4530:256535] ------property_Value = _name-------
2019-11-10 19:18:10.336405+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSString"
2019-11-10 19:18:10.336532+0800 运行时[4530:256535] property_attribute_t_name:C-----property_attribute_t_value:
2019-11-10 19:18:10.336648+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.336770+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_name
2019-11-10 19:18:10.336877+0800 运行时[4530:256535]
2019-11-10 19:18:10.336974+0800 运行时[4530:256535] ------propertyName = Block-------
2019-11-10 19:18:10.337256+0800 运行时[4530:256535] ------property_attr = [email protected]?,C,N,V_Block-------
2019-11-10 19:18:10.337568+0800 运行时[4530:256535] ------propertyType = @?-------
2019-11-10 19:18:10.337972+0800 运行时[4530:256535] ------property_Value = _Block-------
2019-11-10 19:18:10.338296+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@?
2019-11-10 19:18:10.338638+0800 运行时[4530:256535] property_attribute_t_name:C-----property_attribute_t_value:
2019-11-10 19:18:10.341894+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.342363+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_Block
2019-11-10 19:18:10.342769+0800 运行时[4530:256535]
2019-11-10 19:18:10.343143+0800 运行时[4530:256535] ------propertyName = delegate-------
2019-11-10 19:18:10.343664+0800 运行时[4530:256535] ------property_attr = T@"<NSObject>",W,N,V_delegate-------
2019-11-10 19:18:10.343779+0800 运行时[4530:256535] ------propertyType = @"<NSObject>"-------
2019-11-10 19:18:10.344314+0800 运行时[4530:256535] ------property_Value = _delegate-------
2019-11-10 19:18:10.344746+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"<NSObject>"
2019-11-10 19:18:10.345172+0800 运行时[4530:256535] property_attribute_t_name:W-----property_attribute_t_value:
2019-11-10 19:18:10.345485+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.345773+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_delegate
2019-11-10 19:18:10.346062+0800 运行时[4530:256535]
2019-11-10 19:18:10.346475+0800 运行时[4530:256535] ------propertyName = age-------
2019-11-10 19:18:10.346859+0800 运行时[4530:256535] ------property_attr = Ti,N,V_age-------
2019-11-10 19:18:10.347278+0800 运行时[4530:256535] ------propertyType = i-------
2019-11-10 19:18:10.347784+0800 运行时[4530:256535] ------property_Value = _age-------
2019-11-10 19:18:10.348131+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:i
2019-11-10 19:18:10.348551+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.348980+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_age
2019-11-10 19:18:10.349373+0800 运行时[4530:256535]
2019-11-10 19:18:10.349737+0800 运行时[4530:256535] ------propertyName = height-------
2019-11-10 19:18:10.350087+0800 运行时[4530:256535] ------property_attr = Tf,N,V_height-------
2019-11-10 19:18:10.350393+0800 运行时[4530:256535] ------propertyType = f-------
2019-11-10 19:18:10.350763+0800 运行时[4530:256535] ------property_Value = _height-------
2019-11-10 19:18:10.351191+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:f
2019-11-10 19:18:10.351596+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.351971+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_height
2019-11-10 19:18:10.352397+0800 运行时[4530:256535]
2019-11-10 19:18:10.352694+0800 运行时[4530:256535] ------propertyName = weight-------
2019-11-10 19:18:10.353102+0800 运行时[4530:256535] ------property_attr = Td,N,V_weight-------
2019-11-10 19:18:10.353529+0800 运行时[4530:256535] ------propertyType = d-------
2019-11-10 19:18:10.353791+0800 运行时[4530:256535] ------property_Value = _weight-------
2019-11-10 19:18:10.354096+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:d
2019-11-10 19:18:10.354411+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.354693+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_weight
2019-11-10 19:18:10.355023+0800 运行时[4530:256535]
2019-11-10 19:18:10.355303+0800 运行时[4530:256535] ------propertyName = num-------
2019-11-10 19:18:10.355567+0800 运行时[4530:256535] ------property_attr = T@"NSNumber",&,N,V_num-------
2019-11-10 19:18:10.355887+0800 运行时[4530:256535] ------propertyType = @"NSNumber"-------
2019-11-10 19:18:10.356349+0800 运行时[4530:256535] ------property_Value = _num-------
2019-11-10 19:18:10.357784+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSNumber"
2019-11-10 19:18:10.358246+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.358968+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.359325+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_num
2019-11-10 19:18:10.359998+0800 运行时[4530:256535]
2019-11-10 19:18:10.360152+0800 运行时[4530:256535] ------propertyName = date-------
2019-11-10 19:18:10.360572+0800 运行时[4530:256535] ------property_attr = T@"NSDate",&,N,V_date-------
2019-11-10 19:18:10.360834+0800 运行时[4530:256535] ------propertyType = @"NSDate"-------
2019-11-10 19:18:10.361263+0800 运行时[4530:256535] ------property_Value = _date-------
2019-11-10 19:18:10.361579+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSDate"
2019-11-10 19:18:10.361951+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.362362+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.362838+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_date
2019-11-10 19:18:10.363256+0800 运行时[4530:256535]
2019-11-10 19:18:10.363500+0800 运行时[4530:256535] ------propertyName = data-------
2019-11-10 19:18:10.363788+0800 运行时[4530:256535] ------property_attr = T@"NSData",&,N,V_data-------
2019-11-10 19:18:10.364093+0800 运行时[4530:256535] ------propertyType = @"NSData"-------
2019-11-10 19:18:10.364430+0800 运行时[4530:256535] ------property_Value = _data-------
2019-11-10 19:18:10.364925+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSData"
2019-11-10 19:18:10.365110+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.365525+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.365928+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_data
2019-11-10 19:18:10.366541+0800 运行时[4530:256535]
2019-11-10 19:18:10.366648+0800 运行时[4530:256535] ------propertyName = array-------
2019-11-10 19:18:10.366929+0800 运行时[4530:256535] ------property_attr = T@"NSArray",&,N,V_array-------
2019-11-10 19:18:10.367389+0800 运行时[4530:256535] ------propertyType = @"NSArray"-------
2019-11-10 19:18:10.367686+0800 运行时[4530:256535] ------property_Value = _array-------
2019-11-10 19:18:10.368112+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSArray"
2019-11-10 19:18:10.368357+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.368664+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.368905+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_array
2019-11-10 19:18:10.369409+0800 运行时[4530:256535]
2019-11-10 19:18:10.369565+0800 运行时[4530:256535] ------propertyName = dic-------
2019-11-10 19:18:10.369810+0800 运行时[4530:256535] ------property_attr = T@"NSDictionary",&,N,V_dic-------
2019-11-10 19:18:10.370092+0800 运行时[4530:256535] ------propertyType = @"NSDictionary"-------
2019-11-10 19:18:10.370366+0800 运行时[4530:256535] ------property_Value = _dic-------
2019-11-10 19:18:10.370706+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"NSDictionary"
2019-11-10 19:18:10.371128+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.371537+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.371911+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_dic
2019-11-10 19:18:10.372340+0800 运行时[4530:256535]
2019-11-10 19:18:10.372762+0800 运行时[4530:256535] ------propertyName = myObject-------
2019-11-10 19:18:10.373469+0800 运行时[4530:256535] ------property_attr = T@"MyObject",&,N,V_myObject-------
2019-11-10 19:18:10.373751+0800 运行时[4530:256535] ------propertyType = @"MyObject"-------
2019-11-10 19:18:10.374167+0800 运行时[4530:256535] ------property_Value = _myObject-------
2019-11-10 19:18:10.374515+0800 运行时[4530:256535] property_attribute_t_name:T-----property_attribute_t_value:@"MyObject"
2019-11-10 19:18:10.374742+0800 运行时[4530:256535] property_attribute_t_name:&-----property_attribute_t_value:
2019-11-10 19:18:10.375014+0800 运行时[4530:256535] property_attribute_t_name:N-----property_attribute_t_value:
2019-11-10 19:18:10.375595+0800 运行时[4530:256535] property_attribute_t_name:V-----property_attribute_t_value:_myObject
2019-11-10 19:18:10.375718+0800 运行时[4530:256535] 

四、分析

看到上述打印,发现一些特性,可以获取到属性名称、属性类型,属性原子性、属性引用情况等,这些基本都在属性描述property_attr中,并使用一些特别的字符表示,例如T、@,&,N,V等,每一个属性描述都是以字符“T”开头,以字符“V下划线变量名 V_xxx”结尾 (结尾不固定,对于其他属性)。

例如属性name的属性描述打印:

//T:  Type(@encode) 属性类型
//@:  对象类型, NSString类型
//C: Copy  拷贝特性
//N: nonatomic 非原子性,默认为atomic,atomic为空
//V:variable 变量 _name , 使用@property修饰的属性系统默认@synthesize定义下划线变量,_name
property_attr = T@"NSString",C,N,V_name

例如属性age的属性描述打印:

//T:  Type(@encode) 属性类型
//i:  基本数据类型, int类型//N: nonatomic 非原子性,默认为atomic,atomic为空
//V:variable 变量 _age , 使用@property修饰的属性系统默认@synthesize定义下划线变量,_age
property_attr = Ti,N,V_age-------

例如属性myObject的属性描述打印:

//T:  Type(@encode) 属性类型
//@:  对象类型, 自定义类MyObject类型
//&:  引用特性, 强引用
//N: nonatomic 非原子性,默认为atomic,atomic为空
//V:variable 变量 _myObject-- , 使用@property修饰的属性系统默认@synthesize定义下划线变量,_myObject--
property_attr = T@"MyObject",&,N,V_myObject-------

就不一一列举了,基本属性特性大概如下,可能不完整:

//基本字符表示
T  是固定开头,表示类型,后跟类型 @、i、f、d、#等
&  代表强引用
C  代表copy
R  代表readOnly属性,readwrite时为空
W  代表weak,assign为空,默认为assign。
N  区分的nonatomic和atomic,默认为atomic,atomic为空,’N’代表是nonatomic
D  @dynamic 动态特性,动态绑定,需要手动生成setter和getter方法
V_exprice 固定结尾,V代表变量,后面紧跟着的是成员变量名,代表这个property的成员变量名为_exprice。

属性类型的表示字符特性编码苹果官方给了一套参考:特性编码解析大全

//编码值   含意
//c       代表char类型
//i       代表int类型
//s       代表short类型
//l       代表long类型,在64位处理器上也是按照32位处理
//q       代表long long类型
//C       代表unsigned char类型
//I       代表unsigned int类型
//S       代表unsigned short类型
//L       代表unsigned long类型
//Q       代表unsigned long long类型
//f       代表float类型
//d       代表double类型
//B       代表C++中的bool或者C99中的_Bool
//v       代表void类型
//*       代表char *类型
//@       代表对象类型
//#       代表类对象 (Class)
//:       代表方法selector (SEL)
//[array type]  代表array
//{name=type…}  代表struct结构体
//(name=type…)  代表union共同体
//bnum   A bit field of num bits,代表位字段
//^type  A pointer to type,代表指针类型
//?      An unknown type (among other things, this code is used for function pointers),代表未知类型,例如block

四、扩展

类的属性声明

//类拥有一个属性
NS_ASSUME_NONNULL_BEGIN
@interface MyObject : NSObject
@property (nonatomic,   copy) NSString *name;
@end

1、获取

-(void)printPropertyWithObj:(MyObject *)myObject{
  unsigned int count;
  objc_property_t *properties = class_copyPropertyList([myObject class], &count);
  for (int i=0; i<count; i++) {

    //获取属性
    objc_property_t property = properties[i];

    //属性名称
    const char *propertyName = property_getName(property);
    NSLog(@"------propertyName = %s-------",propertyName);

    //属性变量
    char *property_Value = property_copyAttributeValue(property, "V");
    NSLog(@"------property_Value = %s-------",property_Value);

    //属性类型
    char *property_Type = property_copyAttributeValue(property, "T");
    NSLog(@"------property_Type = %s-------",property_Type);
  }
}
2019-11-10 21:57:24.258232+0800 运行时[6007:365556] ------propertyName = name-------
2019-11-10 21:57:24.258412+0800 运行时[6007:365556] ------property_Value = _name-------
2019-11-10 21:57:24.258541+0800 运行时[6007:365556] ------property_Type = @"NSString"-------

2、添加

//添加属性
//* @param cls The class to modify.
//* @param name The name of the property.
//* @param attributes An array of property attributes.
//* @param attributeCount The number of attributes in \e attributes.
//class_addProperty(Classcls, const char *name, const objc_property_attribute_t *attributes,unsigned int attributeCount)
const char * propertyName = "age";
objc_property_attribute_t type = { "T", "i" }; //int
objc_property_attribute_t ownership = { "N" }; //nonatomic
objc_property_attribute_t variable  = { "V", "_age" }; //_age
objc_property_attribute_t attrs[]   = { type, ownership, variable };
BOOL addSuccess = class_addProperty([myObject class], propertyName, attrs, 3);
if (addSuccess) {
   [self printPropertyWithObj:myObject];
}
2019-11-10 22:00:12.120742+0800 运行时[6064:369407] 默认属性如下:
2019-11-10 22:00:12.120941+0800 运行时[6064:369407] ------propertyName = name-------
2019-11-10 22:00:12.121073+0800 运行时[6064:369407] ------property_Value = _name-------
2019-11-10 22:00:12.121199+0800 运行时[6064:369407] ------property_Type = @"NSString"-------
2019-11-10 22:00:12.121295+0800 运行时[6064:369407]
2019-11-10 22:00:12.121405+0800 运行时[6064:369407] 添加属性如下:
2019-11-10 22:00:12.121617+0800 运行时[6064:369407] ------propertyName = age-------
2019-11-10 22:00:12.121731+0800 运行时[6064:369407] ------property_Value = _age-------
2019-11-10 22:00:12.121886+0800 运行时[6064:369407] ------property_Type = i-------
2019-11-10 22:00:12.122279+0800 运行时[6064:369407] ------propertyName = name-------
2019-11-10 22:00:12.122780+0800 运行时[6064:369407] ------property_Value = _name-------
2019-11-10 22:00:12.123222+0800 运行时[6064:369407] ------property_Type = @"NSString"-------

3、替换

//替换属性【注意:无法改变属性名称,只是修改生成的下划线变量,_variable】
//* @param cls The class to modify.
//* @param name The name of the property.
//* @param attributes An array of property attributes.
//* @param attributeCount The number of attributes in \e attributes.
//class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t * _Nullable attributes, unsigned int attributeCount)
const char * propertyName = "name";
objc_property_attribute_t type = { "T", "@\"NSString\"" };//NSString
objc_property_attribute_t ownership = { "C", "N" }; // copy、nonatomic
objc_property_attribute_t variable  = { "V", "_newName" }; //_newName
objc_property_attribute_t attrs[]   = { type, ownership, variable };
class_replaceProperty([myObject class], propertyName, attrs, 3);
[self printPropertyWithObj:myObject];
2019-11-10 22:03:52.448875+0800 运行时[6111:373162] 默认属性如下:
2019-11-10 22:03:52.450451+0800 运行时[6111:373162] ------propertyName = name-------
2019-11-10 22:03:52.452714+0800 运行时[6111:373162] ------property_Value = _name-------
2019-11-10 22:03:52.453001+0800 运行时[6111:373162] ------property_Type = @"NSString"-------
2019-11-10 22:03:52.453125+0800 运行时[6111:373162]
2019-11-10 22:03:52.458433+0800 运行时[6111:373162] 替换属性如下:
2019-11-10 22:03:52.458658+0800 运行时[6111:373162] ------propertyName = name-------
2019-11-10 22:03:52.463156+0800 运行时[6111:373162] ------property_Value = _newName-------
2019-11-10 22:03:52.463973+0800 运行时[6111:373162] ------property_Type = @"NSString"-------

原文地址:https://www.cnblogs.com/XYQ-208910/p/11831430.html

时间: 2024-09-30 20:35:30

分析Runtime的属性Property的相关文章

iOS runtime探究(三): 从runtime开始理解OC的属性property

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639303 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

Yii2基本概念之——属性(property)

学习任何一门学问,往往都是从起基本的概念学起.万丈高楼平地起,这些基本概念就是高楼的基石,必须做详尽的分析.我们知道,Yii2是一款脉络清晰的框架,理顺了基础的概念和基本功能,学习更高级和复杂的功能就容易多了.Yii2是一款纯面向对象的框架,它对类的功能做了扩充:PHP类的功能分为属性和方法,而Yii2定义了类的三个功能:属性(property),行为(behavior)和事件(event). 为了更好的实现面向对象的编程,拿到一个现实的对象,要构造一个PHP对象与之对应,如果用Yii2框架去实

Objective-C基础5 : 属性@property

1.类里面经常有一些变量需要进行set和get操作,OC中提供了方便的属性@property来替换set和get方法,这样能减少频繁且简单的重复代码.如下代码: @interface Person : NSObject @property NSString* strName; @property int nAge; @end @implementation Person @synthesize strName; @synthesize nAge; @end 通过在类声明变量前面添加@proper

作为笔记:Objective-C属性property的一些认识

在头文件中声明: @property (nonatomic,strong) NSString * str; 在oc中,这一行代码表示一个名为str的属性. 在实现文件.m中声明: @synthesize str; 在oc中类中声明了这一句话就会自动生成两个方法(生成属性的getter和setter),一个属性,如果实现了属性(在.m文件中)则会生成一个实例变量. 在类别中声明了了属性则会自动生成两个方法,则必须实现setter和getter,类别中属性要用@dynamic,但是不会生成实例变量.

python静态属性----property

1.什么是静态属性property property是一种特殊的属性,访问它的时候会执行一段功能(函数)然后返回值. 在使用者直接要某个结果的时候,就需要用到了静态属性. 2.例子 计算BMI指数. class People: def __init__(self,name,tz,hit): self.name=name self.tz=tz self.hit=hit @property def bmi(self): return self.tz / (self.hit**2) p=People(

属性(property)与成员变量(ivar)

类内使用成员变量{}, 类外使用属性@property /*********** --- Person.h */ @interface Person : NSObject { NSString *_name; } @property (nonatomic, copy) NSString *sex; @property (nonatomic, assign) int age; - (void)getPropertyAndiVar; @end /*********** --- Person.m */

实例变量(instance var)与属性(@property)的关系

实例变量(instance var)与属性(@property)的关系 Objective-C 2.0之后,声明一个@property name自动产生一个实例变量,名为_name,因此省去实例变量和属性重复输入的麻烦.而使用@synthesize可以改变_name名称.@property和@synthesize不必成对出现. @property name:指示编译器自动合成setter和getter方法,setter方法名即setName,而getter方法名即name.@property后面

属性( @property )与成员变量的那些事 :

属性( @property )与成员变量的那些事 : 属性对成员变量扩充了存取方法 . 属性默认会生成带下划线的成员变量 . 早期的 Xcode 不支持自动合成成员变量的存取方法 , 所以古老的iOS工程师是愤怒的 . 后来 Xcode 智能了一点 , 可以用 @synthesize 关键字自动合成成员变量的存取方法 , 此时的iOS工程师是郁闷的 . 现在 Xcode 会在我们声明属性时自动合成存取方法 , 连@synthesize都不用写了 , 这样iOS工程师彻底解放了 . 顺便提一下 @

区分元素特性attribute和对象属性property

其实attribute和property两个单词,翻译出来都是属性,但是<javascript高级程序设计>将它们翻译为特性和属性,以示区分.本文将详细介绍特性和属性的不同之处 定义 元素特性attribute是指HTML元素标签的特性 下面的id.class.title.a都是特性,其中a叫做自定义特性 <div id="id1" class="class1" title="title1" a='a1'></div