zoukankan      html  css  js  c++  java
  • iOS MRC开发

    1. assign意味着直接赋值,retain意味着release旧值,retain新值

      1.1 @property (assign, nonatomic) UIWindow *window;

         意味着:

         - (void )setWindow:(UIWindow *)window

         {

             _window = window;

         }

        

        // AppDelegate.m

       // 因为是assign,所以不会对[[UIWindow alloc]init]产生的对象做retain操作. 在自动释放池释放时,引用计数器会由1变成0,AppDelegate不能长期拥有该Window

          self.window = [[[UIWindow alloc]init]autorelease];

          //既然自动释放池释放时,会把产生的Window销毁,不添加autorelease呢?这样不符合内存管理原则,这么做意味着,产生的Window永远无法销毁

          self.window.backgroundColor = [UIColor redColor];

          self.window.frame = [UIScreen mainScreen].bounds;

          [self.window makeKeyAndVisible];

          return YES;

       

          // 如果用下面修改上面的代码为下面这样,貌似AppDelegate既可以长期拥有Window,AppDelegate释放时,也可以销毁Window

          self.window = [[UIWindow alloc]init];

         // 潜在问题是,如果对self.window重复赋值,例如再写一行代码 self.window = [[UIWindow alloc]init]. AppDelegate释放时,就无法销毁旧的Window

          self.window.backgroundColor = [UIColor redColor];

          self.window.frame = [UIScreen mainScreen].bounds;

          [self.window makeKeyAndVisible];

          return YES;

        

       - (void)dealloc{

            [self.window release];

            [super dealloc];

       }

      1.2 @property (retain, nonatomic) UIWindow *window;

        意味着:

        - (void )setWindow:(UIWindow *)window

        {

            if (_window != window) {

                  [_window release];

                    _window = [window retain];

            }

        }

        

        // AppDelegate.m

        // 因为是retain,所以会对[[UIWindow alloc]init]产生的对象做retain,在自动释放池释放时,会由2变成1,AppDelegate可以长期拥有该Window

          self.window = [[[UIWindow alloc]init]autorelease]; 

          self.window.backgroundColor = [UIColor redColor];

          self.window.frame = [UIScreen mainScreen].bounds;

          [self.window makeKeyAndVisible];

          return YES;

        

       // 为了防止内存泄露,在AppDelegte销毁的时候,要对拥有的window做release操作

       - (void)dealloc{

            [self.window release];

            [super dealloc];

       }

      

    2.非ARC内存管理的由来

      2.1 准备:  

    -------------Dog----------Begin-------------

    #import <Foundation/Foundation.h>

    @interface Dog : NSObject

    @end

    #import "Dog.h" 

    @implementation Dog

    - (void)dealloc

    {

        NSLog(@"Dog--dealloc");

        [super dealloc];

    }

    @end

    -------------Dog----------End-------------

    -------------Person----------Begin-------------

    #import <Foundation/Foundation.h>

    @class Dog;

    @interface Person : NSObject

    {

        Dog *_dog;

    }

    - (void)setDog:(Dog *)dog;

    - (Dog *)dog;

    @end

    #import "Person.h"

    @implementation Person

    - (void)setDog:(Dog *)dog

    {

        _dog = dog;

    }

    - (Dog *)dog

    {

        return _dog;

    }

    - (void)dealloc

    {

        NSLog(@"Person--dealloc");

        [super dealloc];

    }

    @end

    -------------Person----------End-------------

      2.2 原始版本

    -------------MainViewController----------Begin-------------

        Dog *d = [[Dog alloc]init];

        Person *p =[[Person alloc]init];

       p.dog = d;    

       

      [d release];

        NSLog(@"p.dog----%@",p.dog); //僵尸对象

        [p release];

    -------------MainViewController----------End-------------

      2.3 优化,解决僵尸对象的问题

      修改Person的Set方法

    - (void)setDog:(Dog *)dog

    {

        _dog = [dog retain]; // 这样MainViewController就不会访问僵尸对象

    }

    - (void)dealloc

    {

        NSLog(@"Person--dealloc");

      [self.dog release]; //谁retain,谁release

        [super dealloc];

    }

      2.4 存在的问题:重复赋值时,Person销毁时,只能释放最新持有的Dog,旧Dog内存泄露

        Dog *d = [[Dog alloc]init];

      Dog *d2 = [[Dog alloc]init];

        Person *p =[[Person alloc]init];

       p.dog = d;

         p.dog = d2;

       

      [d release];

        NSLog(@"p.dog----%@",p.dog); 

        [p release];

      2.5 优化:解决重复赋值的问题

    - (void)setDog:(Dog *)dog

    {

      [_dog release];

        _dog = [dog retain]; 

    }

      2.6 存在的问题:重复赋值同一条狗,会出现野指针错误

        Dog *d = [[Dog alloc]init];

        Person *p =[[Person alloc]init];

       p.dog = d;

         p.dog = d; // 执行到这一行时,会出现野指针错误

       

      [d release];

        NSLog(@"p.dog----%@",p.dog); 

        [p release];

      2.7 优化:在set方法加判断

    - (void)setDog:(Dog *)dog

    {

        if (_dog != dog) { 

            [_dog release];

            _dog = [dog retain];

        }

    }

    3. 属性用retain相当于生成了2.6优化之后set/get方法;如果用assign,2.6优化之后的set方法还的写上,这样对象才能长期持有该属性

      3.1 修改person.h

      @interface Person : NSObject

      @property (retain,nonatomic) Dog *dog;

      @end

      3.2 修改person.m,dog的set方法和get可以去掉了

    4. 总结,做非ARC开发

       1>要长期持有一个属性用retain.  注:一般情况,属性除了UI控件,一般都是想长期持有的

         2>在dealloc方法里,要释放:

        写法一:[self.属性名 release];

             _属性名 = nil;

        写法二:[_属性名 release]; 

             _属性名 = nil;

        写法三:[self.属性名 nil];

    5. 

  • 相关阅读:
    WCF Data Contract之集合类型
    LINQ To DataSet
    WCF Data Contract之枚举
    初识Parallel Extensions之TPL(二)
    初识Parallel Extensions之TPL
    java北京行之单例模式的引入
    Strut2 入门
    解决 Eclipse 下使用 Ant 编译出现问题: 警告:编码 GBK 的不可映射字符
    解决 Ant 非法字符: \65279
    [原创]Visual Studio 中引用 Flash 控件
  • 原文地址:https://www.cnblogs.com/oumygade/p/4281367.html
Copyright © 2011-2022 走看看