iOS RunTime 学习记录3_属性、实例变量、修饰符

前言:我是参考 南峰子 的博客加上自己理解写的,原著专辑大家自己可看:http://southpeak.github.io/categories/objectivec/

一、 先说说属性(property)和成员变量 (instance var(Ivar))的区别

其实主观上,自己认为:属性就是我们平时在.h中用@property关键字声明的东西,而实例变量是我们在.h.m中用{}声明的东西。

@interface ViewController : UIViewController{
    
    NSInteger integer1;         //实例变量
}

@property (assign,nonatomic) NSInteger integer2;    //实例属性
  1. 一般我们在使用@property声明的属性,如果没在.m文件中使用@synthesize同步的话,系统会默认生成一个与属性对应的实例变量。如上面的代码,我们在.m中可以直接通过访问_integer2。如果使用在.m文件中使用@synthesize同步的话,如:@synthesize integer2,那么属性对应的成员变量就不是_integer2,而是integer2,就得到一个和属性名称一样的实例变量。当然@synthesize语句也可以用户指定当前属性和那个成员变量绑定,如@synthesize integer2 = integer1,这样写就制定了属性integer2和实例变量integer1绑定了。
  2. 在我们使用self.integer2,因为integer2是通过使用@property来声明的属性,我们使用的时候一般是通过self.来使用,其实是系统分装的setter 和 getter方法,我们看是通过一个小点.访问属性,其实执行是方法(据说这是当时OC设计者估计和Java学的),通过方法去给对应的实例变量(_integer2)读取赋值的。为什么这样做了,其实是我们读取写入的时候会更具我们跟在@property后面括号(assign,nonatomic)声明的关键字去管理实例变量的内存,如retain,copy等。
  3. 如果我们直接访问实例变量可以通过直接调用实例变量的名字或通过self->实例变量名字访问,这时候的内存管理方式我们没有指定,其实就是直接赋值(assign),而属性可以通过修饰词加上getter和setter方法实现丰富的内存管理方式。

PS:以前碰到一个小问题http://www.jianshu.com/p/ded24cade177可以直观的解释

二、修饰符

逃也逃不掉,该弄懂的还是要弄的

1.原子性(Atomicity)包含:nonatomic;
2.读写属性(Writability)包含:readwrite / readonly;
3.setter语义(Setter Semantics)包含:assign / retain / copy;

1. 原子性
nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。默认值是atomic,为原子操作。(atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)

2. 读写属性
readwrite / readonly:决定是否生成set访问器,readwrite是默认属性,生成getter和setter方法;readonly只生成getter方法,不生成setter方法。readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用
注意:readwrite/readonly配合使用:属性在外部是只读,自己使用时读写使用self->实例变量直接读或写

3. setter语义
这些属性用于指定set访问器的语义,也就是说,这些属性决定了以何种方式对数据成员赋予新值。
--assign:直接赋值,索引计数不改变,适用于简单数据类型,例如:NSIngeter、CGFloat、int、char等。
--retain(strong):指针的拷贝,使用的是原来的内存空间。对象的索引计数加1。此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数)。
--copy:对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间。新对象的索引计数为1。此属性只对那些实行了NSCopying协议的对象类型有效。

  • 很多Objective-C中的object最好使用用retain(strong),一些特别的object(例如:string)使用copy

三、实例变量 和 属性在RunTime中关联的方法

实例变量: 英文Instance var 简写:Ivar,在OC中也是使用结构体objc_ivar定义一个Ivar,其结构体定义如下:

struct objc_ivar {
    char *ivar_name                                          OBJC2_UNAVAILABLE;
    char *ivar_type                                          OBJC2_UNAVAILABLE;
    int ivar_offset                                          OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
}                                                            OBJC2_UNAVAILABLE;

关于成员变量的一些方法:

/** 获取成员变量名 */
OBJC_EXPORT const char *ivar_getName(Ivar v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

/**获取成员变量类型编码 */
OBJC_EXPORT const char *ivar_getTypeEncoding(Ivar v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

/** 获取成员变量的偏移量 */
OBJC_EXPORT ptrdiff_t ivar_getOffset(Ivar v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

对于类型id或其它对象类型的实例变量,可以调用object_getIvar
和object_setIvar来直接访问成员变量,而不使用偏移量

属性: property ,在OC中使用结构体objc_property定义objc_property_t表示属性(我没有找到objc_property结构体的具体声明)。另外,OC中使用结构体objc_property_attribute_t定义一个属性的描述信息,它的定义如下:

/// Defines a property attribute
typedef struct {
    const char *name;           /**< The name of the attribute */
    const char *value;          /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;

属性常用的方法:

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

// 获取属性特性描述字符串
const char * property_getAttributes ( objc_property_t property );

// 获取属性中指定的特性
char * property_copyAttributeValue ( objc_property_t property, const char *attributeName );

// 获取属性的特性列表
objc_property_attribute_t * property_copyAttributeList ( objc_property_t property, unsigned int *outCount )1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 上一篇边缘人系列,还是几个月前那篇抑郁症患者的自白。 发表在首页之后,一个坚持不懈的上海小姐姐坚定地说。 我就是你...
    一只奶牛阅读 6,413评论 0 11