zoukankan      html  css  js  c++  java
  • ios内存管理笔记(三)

    我们在进行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的命名,籍此来保护变量不会被不恰当的访问。这样的话还需要在dealloc中使用此_window来release。但是使用时最好还是使用self,因为这样才会去调用set和get方法。对于一些情况,比如alloc对象,那么就不要直接拿self.variable作为左值,因为这样的话会内存泄漏,因为使用self会和声明时的property来匹配,如果是retain的话那么这样做计数器变成2。最好的方法就是定义一个临时的变量去alloc然后self.variable = 临时变量,使用完成后[临时变量  release]就可以了。

    下面是一个常见的例子
    写法一:
    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; 这才是最可靠的方法。

  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/lisa090818/p/3216753.html
Copyright © 2011-2022 走看看