OC中的实例变量(Instance Variable)与属性(Property)
在工程中新建一个XYZPerson类,如下所示:
#import <Foundation/Foundation.h>
@interface XYZPerson : NSObject
@property NSString* firstName;
-(void)getIVSize;
-(void)getPrptySize;
-(void)printAddressOfIV;
@end
它包含一个firstName属性,经过这样的声明,编译器会为firstName自动生成Accessor(setter和getter)和实例变量。因为在外部无法访问到自动生成的实例变量_firstName,所以在类中声明了一个getIVSize方法用于得到实例变量的大小,以及一个printAddressOfIV方法得到实例变量的地址。
- main函数中的内容如下:
int main(void)
{
XYZPerson* p = [[XYZPerson alloc]init];
//如果没有用下面这句话为属性赋值,则实例变量没有被分配空间。
//当使用下面这句赋值之后,实例变量_firstName长度为8字节,证明它是指针?这个指针的长度为8字节?的确是8字节
[p setFirstName:@"haha"];
[p getIVSize];
NSLog(@"%@",[p firstName]);
NSLog(@"size of pointer q is %li",sizeof(p));
//以上证明了一个东西:实例变量也是一个指针,它才最终指向对象的存储空间
//那属性指向的位置是实例变量的地址么?
//OC完全将用户和实际存储空间隔离开来,对于内存管理都是自动完成
NSLog(@"%p",(p.firstName)); //输出firstName属性指针内的地址,即它指向的位置。
[p printAddressOfIV]; //输出实例变量指向的地址。
//结果是实例变量和属性指针都指向同一个位置
NSLog(@"%p",p); //输出对象指针指向的地址
return 0;
}
说明:
- 首先定义了一个XYZPerson对象,并对其初始化。
XYZPerson* p = [[XYZPerson alloc]init];
- 因为没有自定义初始化,故上面的语句并不会为属性对象分配空间,即属性为nil。
- 所以用下面这句,为firstName属性赋值一个字面量,使用的是自动生成的setter方法。
[p setFirstName:@"haha"];
经过上面的过程,一个对象内的内容都被分配到了空间:
[p getIVSize];
NSLog(@"%@",[p firstName]);
NSLog(@"size of pointer p is %li",sizeof(p));
上面三行代码中,首先输出实例变量_firstName的大小,然后输出firstName属性值(使用自动生成的getter方法,方法名与属性名相同),最后一行输出的是指针p的大小,如下所示:
Size of Instance Variable _firstName is 8
haha
size of pointer p is 8
说明属性和实例变量的大小都是8个字节。
再来看下面的:
NSLog(@"%p",(p.firstName)); //输出firstName属性指针内的地址,即它指向的位置。
[p printAddressOfIV]; //输出实例变量指向的地址。
这两行中,第一行输出对象p的firstName属性地址,第二行输出实例变量_firstName的地址,结果如下:
0x1000010c8
0x1000010c8
证明两个都指向同一片内存空间,但是这个内存地址的内容到底是存放的对象的字符串属性真实的地址,还是其他中间层的内容,还有待考证。
对属性和实例变量的讨论就此结束?