成员变量、实例变量、属性

  • 成员变量和实例变量
    Objective-C 引入了“实例变量"的概念,但同时, 也经常出现 “成员变量”的声音。 到底什么是实例变量,什么是成员变量,二者的区别是什么呢?
    如果你之前接触过C++, Java对成员变量(member varialbe) ,肯定不陌生。 今天,你又看到了这个熟悉的叫法, 定会感到 Objective-C 没想象中的那么难。
    上图:

图中的Member Variable declarations翻译过来就是成员变量的声明
貌似 { } 中所声明的变量都为成员变量。 既然如此,实例变量又是什么意思呢?
既然OC的表达方式是英文, 不妨从英文中查知原本的含义。

类: Class (description/template for an object)
实例: Instance (manifestation of a class)
消息: Message (sent to object to make it act)
方法: Method (code invoked by a Message)
实例变量: Instance Variable (object-specific storage)
超类/子类: Superclass/Subclass (Inheritance)
协议:  Protocol (non-class-specific methods)

从给出的英文说明,可以看出:实例(Instance)是针对 类(class)而言的。实例是指类的声明;由此推理,实例变量(Instance Variable) 是指由类声明的对象
严格说来,上图中的 int count; 是一个成员变量。
而 *NSString name; 是一个实例变量(NSString是一个类)。
至于 id data 应该属于成员变量还是实例变量呢? 因为 id 是 OC特有的类型。从本质上讲, id 等同于 (void *)。 所以 id data 应属于 实例变量。
说清实例变量和成员变量接下来我们说说属性。

  • 类Class中的属性property
    在ios第一版中,我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如:

    @interface MyViewController :UIViewController
    { 
        UIButton *myButton;
    }
    @property (nonatomic, retain) UIButton *myButton;
    @end
    

在现在iOS版本中:苹果将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。因此,在这个版本中,我们不再为输出口声明实例变量。

  例如:MyViewController.h文件
      @interface MyViewController :UIViewController
      @property (nonatomic, retain) UIButton *myButton;
      @end

在MyViewController.m文件中,编译器也会自动的生成一个实例变量_myButton。那么在.m文件中可以直接的使用_myButton实例变量,也可以通过属性self.myButton.都是一样的。
  注意这里的self.myButton其实是调用的myButton属性的getter/setter方法。这与C++中点的使用是有区别的,C++中的点可以直接访问成员变量(也就是实例变量)。
  例如在oc中有如下代码

       @interface MyViewController :UIViewController
      { 
      NSString *name;
      }
      @end

.m文件中,self.name 这样的表达式是错误的。xcode会提示你使用->,改成self->name就可以了。因为oc中点表达式是表示调用方法,而上面的代码中没有name这个方法。
  oc语法关于点表达式的说明:"点表达式(.)看起来与C语言中的结构体访问以及java语言汇总的对象访问有点类似,其实这是oc的设计人员有意为之。如果点表达式出现在等号 = 左边,该属性名称的setter方法将被调用。如果点表达式出现在右边,该属性名称的getter方法将被调用。"
  所以在oc中点表达式其实就是调用对象的setter和getter方法的一种快捷方式, 例如:dealie.blah = greeble 完全等价于 [dealie.blah setBlah:greeble];
  以前的用法,声明属性跟与之对应的实例变量:

   @interface MyViewController :UIViewControlle
  { 
  UIButton *myButton;
  }
  @property (nonatomic, retain) UIButton *myButton;
  @end

这种方法基本上使用最多,现在大部分也是在使用,因为很多开源的代码都是这种方式。但是ios5更新之后,苹果是建议以以下的方式来使用:

 @interface MyViewController :UIViewController
 @property (nonatomic, retain) UIButton *myButton;
 @end

因为编译器会自动为你生成以下划线开头的实例变量_myButton,不需要自己手动再去写实例变量。而且也不需要在.m文件中写@synthesize myButton,也会自动为你生成setter,getter方法。
@synthesize的作用:
(1)让编译器为你自动生成setter与getter方法。
(2)可以指定与属性对应的实例变量,
例如:
@synthesize myButton = xxx;
那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。
现在:如果.m文件中写了@synthesize myButton,那么生成的实例变量就是myButton;如果没写@synthesize myButton,那么生成的实例变量就是_myButton。所以跟以前的用法还是有点细微的区别。

  • 类别中的属性property
    类与类别中添加的属性要区分开来,因为类别中只能添加方法,不能添加实例变量。经常会在ios的代码中看到在类别中添加属性,这种情况下,是不会自动生成实例变量的。
    比如在:UINavigationController.h文件中会对UIViewController类进行扩展

    @interface UIViewController (UINavigationControllerItem)
    @property(nonatomic,readonly,retain) UINavigationItem *navigationItem;
    @property(nonatomic) BOOL hidesBottomBarWhenPushed;
    @property(nonatomic,readonly,retain) UINavigationController *navigationController;
    @end
    

这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。
  注意一点,匿名类别(匿名扩展)是可以添加实例变量的,非匿名类别是不能添加实例变量的,只能添加方法,或者属性(其实也是方法)。
参考博客:
链接地址一

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

推荐阅读更多精彩内容