2012-05-10 145 views
0

什么我现在有是内存泄漏问题,内存管理

classA.h

@interface ClassA: NSObject <DelegateA> 
-(id)initWithData:(NSData*)data; 
+(Stores*)makeClass:(Class) name fromData:(NSData*)data; 
@property (assign) NSMutableArray *arr; 
@property (assign) RXMLElement  *rxmlRoot; 
@end 

classA.m

-(id)initWithData:(NSData*)data { 
     self = [super init]; 
     if (self) { 
      arr  = [[NSMutableArray array] retain]; 
      rxmlRoot = [[RXMLElement elementFromXMLData:data] retain]; 

     } 

     [rxmlRoot iterate:node with:^(RXMLElement *e){ <--------get warning at here 
      NSLog(@"element is %@",e.tag); 
      Detail *detail = [[[Detail alloc] init] autorelease]; 
      [detail setLat:  [e attribute:@"lat"]]; 
      [detail setLon:  [e attribute:@"lon"]]; 

      [arr addObject:detail]; 

     }]; 
     return self; 
     } 

     +(classA*)makeClass:(Class) name fromData:(NSData*)data{ 
      ClassA *classA = [[ClassA alloc] initWithData:data]; 
      return [storeClass autorelease] ; 

     } 

和RaptureXML.m

+ (id)elementFromXMLData:(NSData *)data { 
    return [[[RXMLElement alloc] initFromXMLData:data] autorelease]; 
} 
- (id)initFromXMLData:(NSData *)data { 
    if ((self = [super init])) { 
     xml_ = [[TBXML alloc] initWithXMLData:data]; 
     tbxmlElement_ = xml_.rootXMLElement; 
    } 

    return self;  
} 

警告:实例变量访问(通过“自我”)导致空指针引用

问题:为什么我收到这样的警告,以及如何解决这个问题。 请在此建议我。由于

+0

是在CLASSA * CLASSA =第一和第三CLASSA [[CLASSA的alloc] initWithData:数据];小写,因为它是一个错字? – fsaint

+0

谢谢你。我刚刚编辑 – tranvutuan

回答

1

尝试将你所有的初始化代码在

if (self) { 

} 

是移动[rxmlrRoot itertate ...等。成if语句

作为一般规则,所有的初始化语法(一切都在init方法!)应该是,如果(个体经营)块。原因是该块之外的代码会在超类返回nil时运行(认为否则如果(!self){...)。如果超级方法(初始化程序只是O-C中的常规方法)未被调用,则不希望代码继续执行。

我还教总是在我的自定义类的指定初始化(这是一个得到调用超级初始化),在我班上所有其他initialzers然后再调用这个指定的初始化。防爆。

// Designated initializer 
- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // initialize some stuff 
    } 

    // else { something went wrong and super returned nil.. 
    // don't put anything here 

    return self; 
} 

// Another initializer 
- (id)initWithFoo:(int)foo 
{ 
    self = [self init]; // Now i call my designated initializer instead of super 
    if (self) { 
     self.foo = foo; // or something 
    } 
} 

允许您控制来自该点的所有流量。

+0

谢谢,警告消失了,但我也需要警告的解释。 – tranvutuan

+2

你说自己可能是零,所以编译器说 - 在自己是零的情况下,当你到达使用其他零事件如'arr'的代码时,你会崩溃。你当然'知道'自己永远不会是零(如果你的内存不足,你肯定会崩溃!) - 但编译器不知道这一点。 –

+0

@ttran Tom说的完全正确,我已经给答案添加了一个解释。类似的问题:http://stackoverflow.com/questions/10246945/instance-variable-access-via-self-results-in-a-null-pointer-dereference – Patrick

0

在呼叫[rxmlRoot iterate:node with:^(RXMLElement *e){ ... }],什么是节点?它不是一个本地变量或一个iVar。它是全球性的还是存在于其他地方?

是什么都检查,以确保这已被初始化。

0

块内,该实例变量arr正在由参考访问。由于细微的内存管理规则,访问导致该块保留self

由于if (self)是编译器的线索,self可能为零,则块的隐式保留self可能会导致空指针解除引用。

要修复,检查零和出口初:

if (!(self = [super init])) { 
    return nil; 
} 

// now it is impossible for self to be nil and cause a null pointer dereference 
// when self is implicitly retained by the block 

// ...continue initialization