代码之家  ›  专栏  ›  技术社区  ›  cdnicoll

数组保留问题

  •  0
  • cdnicoll  · 技术社区  · 16 年前

    我对Objective-C还比较陌生,但是大部分都很清楚,但是当涉及到记忆管理时,我有点缺了。目前,我的应用程序所做的是在nsurlconnection期间 -(void)connectionDidFinishLoading:(NSURLConnection *)connection 我输入了一个方法来解析一些数据,将其放入一个数组中,然后返回该数组。但是,我不确定这是否是最好的方法,因为我没有在自定义方法(方法1,请参见附加的代码)中从内存中释放数组。

    下面是一个小脚本,可以更好地显示我在做什么

    h文件

    #import <UIKit/UIKit.h>
    
    @interface memoryRetainTestViewController : UIViewController {
    
        NSArray *mainArray;
    
    }
    
    @property (nonatomic, retain) NSArray *mainArray;
    
    @end
    

    m文件

    #import "memoryRetainTestViewController.h"
    
    @implementation memoryRetainTestViewController
    @synthesize mainArray;
    
    
    // this would be the parsing method
    -(NSArray*)method1
    {
        // ???: by not release this, is that bad. Or does it get released with mainArray
        NSArray *newArray = [[NSArray alloc] init];
        newArray = [NSArray arrayWithObjects:@"apple",@"orange", @"grapes", "peach", nil];
    
        return newArray;
    }
    
    
    // this method is actually
    // -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    -(void)method2
    {
        mainArray = [self method1];
    }
    
    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    - (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
        [super didReceiveMemoryWarning];
    
        // Release any cached data, images, etc that aren't in use.
    }
    
    - (void)viewDidUnload {
        mainArray = nil;
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    - (void)dealloc {
        [mainArray release];
        [super dealloc];
    }
    
    
    @end
    
    2 回复  |  直到 16 年前
        1
  •  2
  •   Georg Fritzsche    16 年前

    你的 -method1 首先创建一个新数组,然后用新数组覆盖它:

    NSArray *newArray = [[NSArray alloc] init]; // first array, retained
    newArray = [NSArray arrayWithObjects:...];  // second array, auto-released, 
                                                // pointer to first one lost
    

    第一个阵列就是漏在这里的。您还泄漏了存储在ivar中的数组,只需使用合成的setter来避免这种情况——它为您保留和发布。

    如果您还没有这样做,请阅读 Memory Management Guide 可可。

    更好的版本:

    - (NSArray *)method1 {
        NSArray *newArray = [NSArray arrayWithObjects:...];    
        return newArray;
    }
    
    - (void)method2 {
        self.mainArray = [self method1];
    }
    
        2
  •  2
  •   Jack    16 年前

    是的,你的 newArray 在以下情况下释放 mainArray 被释放。但这只是如果 method2 被称为一次。

    我们说的是参考文献,所以如果你有

    newArray = something
    mainArray = newArray
    [mainArray release]
    

    两个变量都将引用 NSArray* . 那么在你的情况下 尼瓦雷 只是本地的,所以没问题。

    如果您拨打 方法2 两次:

    newArray = something
    mainArray = newArray
    newArray = something2
    mainArray = newArray <- old reference is lost
    [mainArray release] <- just something2 is released
    

    为了避免这个问题,你应该确保释放 主阵 在用另一个对象覆盖引用之前。

    编辑:没有注意到您创建了两次数组:)不,那不好..

    推荐文章