我经常遇到一个NSArray关于内存的问题,十分不解,举个例子:
test.h
1、@interface test : UITableViewController{
2、  NSArray *documentArray;}
3、@property(retain,nonatomic)  NSArray *documentArray;
4、@endtest.m
@implementation test
@synthesize documentArray;
6、- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
7、       self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
8、       if(self!=nil){
9、        documentArray=[[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil];
10、      return self;}
11、.....  我在第3行代码 在property用到了retain ,从理论上上说,documentArray的retainCount已经为1了,so第9行代码可以这样写:
 documentArray=[NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];但是有时候这样写,程序会出现错误,有时候不会出错 纠结中...

解决方案 »

  1.   

    retain,是说明该属性在赋值的时候,先release之前的值,然后再赋新值给属性,引用再加1。实际上还是1。第一次给它赋值没问题,第二次给它赋值的时候就得小心了。
      

  2.   

    self.documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];
      

  3.   

    这位大侠的意思我基本上明白了,但是还想确认一下:就本贴而言,在.m文件中我们是应该
    用self.documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];
    还是self.documentArray = [[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil];2、问什么有时候用一种会出现错误呢,我保证documentArray只赋值过一次(因为出错的那次练习,中我只需要将集合数组赋一个不变的值,以便在下面的UITableView中运用,so我敢保证)
      

  4.   

    NSLog(@"documentArray retainCount:%d",[documentArray retainCount]);
    self.documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];
    NSLog(@"documentArray retainCount:%d",[documentArray retainCount]);NSLog(@"documentArray retainCount:%d",[documentArray retainCount]);
    self.documentArray = [[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil];
    NSLog(@"documentArray retainCount:%d",[documentArray retainCount];
    两种方式的结果在赋值前、后分别相同(赋值前retainCount为0,后为1)为什么有时候出错了呢,纠结中...
      

  5.   

    http://stackoverflow.com/questions/4636146/when-to-use-retaincount
      

  6.   

    其实还是属性的使用方面的问题,只有self.documentArray=的时候是用属性的,直接documentArray=是赋值没用到属性。self.documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil]; // 属性给retain了一下,你需要释放1次。
    self.documentArray = [[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil]; //属性给retain了一下,alloc有一下, 你需要释放2次。
    documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil]; //没有retain和alloc,后面用就会异常。
    documentArray = [[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil];//alloc了一下,你需要释放1次。其实这个问题说明你对属性(property)的理解不够深入。你可以看一下苹果的这篇文档,还有网上的一些其他资料。
    https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
      

  7.   

    这个问题新手一般都会碰到,其实总结起来还是内存的问题,即使设置了property,只有再用了self去使用时才会生效。不要把interface中声明的对象,和用property中retain的对象等同起来,它们其实关系不大的。你可以把第二行中的2、 NSArray *documentArray;去掉,然后用self.documentArray = [NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];   这样就万无一失了,或者把第三行中的@property(retain,nonatomic) NSArray *documentArray;去掉,用documentArray=[NSArray arrayWithObjects: @"aa",@"bb", @"cc",nil];或者documentArray = [[NSArray alloc]initWithObjects: @"aa",@"bb", @"cc",nil];都可以。
    个人建议,除非对象要在另一个类中被使用,不然不要设置成property,内部使用,用成员变量足够了,不需要用到属性。
      

  8.   

    谢谢,xiaowei4895 和Linux_fay两位了。