zoukankan      html  css  js  c++  java
  • iOS开发中常见的语句@synthesize obj = _obj 的意义详解

    我们在进行iOS开发时,经常会在类的声明部分看见类似于@synthesize window=_window; 的语句,那么,这个window是什么,_ window又是什么,两个东西分别怎么用,这是一个比较基本的问题,也关乎我们理解Objective-C中对类、类的属性、类的存取器、类的局部变量的统一理解。

    在32位系统中,如果类的 @interface 部分没有进行 ivar 声明,但有 @property 声明,在类的 @implementation 部分有响应的 @synthesize,则会得到类似下面的编译错误:
    Synthesized property 'xX' must either be named the same as a compatible ivar or must explicitly name an ivar
    在 64-bit时,运行时系统会自动给类添加 ivar,添加的 ivar 以一个下划线"_"做前缀。
    上面声明部分的 @synthesize window=_window; 意思是说,window 属性为 _window 实例变量合成访问器方法。
    也就是说,window属性生成存取方法是setWindow,这个setWindow方法就是_window变量的存取方法,它操作的就是_window这个变量。通过这个看似是赋值的这样一个操作,我们可以在@synthesize 中定义与变量名不相同的getter和setter的命名,籍此来保护变量不会被不恰当的访问。

    下面是一个常见的例子
    写法一:
    C代码  收藏代码
    1. @interface MyClass:NSObject{    
    2.         MyObjecct *_myObject;  
    3. }  
    4. @property(nonamtic, retain) MyObjecct *myObject;  
    5. @end  
    6.   
    7. @implementatin MyClass  
    8. @synthesize myObject=_myObject;  

    写法二:
    C代码  收藏代码
    1. @interface MyClass:NSObject{  
    2.         
    3. }  
    4. @property(nonamtic, retain) MyObjecct *myObject;  
    5. @end  
    6.   
    7. @implementatin MyClass  
    8. @synthesize myObject=_myObject;  
    这个类中声明了一个变量_myObject,又声明了一个属性叫myObject,然后用@synthesize生成了属性myObject的存取方法,这 个存取方法的名字应该是:setmyObject和getmyObject。@synthesize myObject=_myObject的含义就是属性myObject的存取方法是做用于_myObject这个变量的。这种用法在Apple的 Sample Code中很常见。
    弄明白了这个语句的意思之后,我们也就清楚了myObject和_myObject的区别,那么,在使用的时候,有什么需要注意的地方,大家应该也都清楚了。是的,myObject是属性,而_ myObject才是变量,我们最终操作的变量都是myObject。
    那么,同样是存取操作,语句
    C代码  收藏代码
    1. self.nameVarPtr = [[ObjectName alloc] init]   
    C代码  收藏代码
    1. nameVarPtr = [[ObjectName alloc] init]  
    两种赋值方式的区别何在呢?

    self.nameVarPtr=xxx 这种赋值方式等价于调用 [self setnameVarPtr:xxx], 而setnameVarPtr:xxx的方法的实现又是依赖于@property的属性的,比如retain,assign等属性。

    nameVarPtr = xxx 的赋值方式,仅仅是对一个指针进行赋值。nameVarPtr仅仅是一个指针变量,记录了xxx的地址。在这个过程中不会调用setter方法,不会调用 setter方法,就和@property没有关系,从而,也和retain,assign等属性没有关系。这种赋值方式就是一个简单的指针赋值。

    综上,对成员变量进行赋值,为防内存泄露需要注意的点:

    1.self调用setter方法的方式

    ObjectName*  tmp= [[ObjectName alloc] init];

    self.nameVarPtr =tmp;                 //retainCount=2

    [tmp release];                               //retainCount=1

    2.指针赋值方式,不会调用setter方法

    nameVarPtr= [[ObjectName alloc] init]; // retainCount=1

    所以,笔者建议大家在对某个变量进行赋值操作的时候,尽量要写self.myObj = xxx; 这才是最可靠的方法。

  • 相关阅读:
    SCI写作经典替换词,瞬间高大上!(转)
    最佳化常用测试函数 Optimization Test functions
    算法复杂度速查表
    VS 代码行统计
    CPLEX IDE 菜单栏语言设置( 中文 英文 韩文 等多国语言 设置)
    如何从PDF文件中提取矢量图
    Matlab无法打开M文件的错误( Undefined function or method 'uiopen' for input arguments of type 'char)
    visual studio 资源视图 空白 解决方案
    MFC DialogBar 按钮灰色不响应
    嗨翻C语言笔记(二)
  • 原文地址:https://www.cnblogs.com/welhzh/p/4293040.html
Copyright © 2011-2022 走看看