0

我现在拥有的是

类A.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

班A.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;    
}

警告:实例变量访问(通过'self')导致空指针取消引用

问题:为什么我收到此警告以及如何解决此问题。请就此给我建议。谢谢

4

3 回答 3

1

尝试将所有初始化代码放入

if (self) {

}

那就是移动 [rxmlrRoot 迭代...等。进入那个 if 语句

作为一般规则,所有初始化语法(init 方法中的所有内容!)都应该在 if (self) 块中。原因是当超类返回 nil 时,该块之外的代码将运行(想想 else if (!self) {...)。如果未调用超级方法(初始化程序只是 OC 中的常规方法),您不希望代码继续执行。

我还被教导在我的自定义类中始终有一个指定的初始化程序(这是可以调用 super init 的那个),我的类中的所有其他初始化程序然后调用这个指定的初始化程序。前任。

// 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
    }
}

这使您可以控制从那一点开始的所有流量。

于 2012-05-10T18:41:22.873 回答
0

在通话[rxmlRoot iterate:node with:^(RXMLElement *e){ ... }]中,什么是节点?它不是局部变量,也不是 iVar。它是全球性的还是存在于其他地方?

不管它是什么,检查以确保它已被初始化。

于 2012-05-10T20:08:08.917 回答
0

在块内部,arr通过引用访问实例变量。由于微妙的内存管理规则,访问导致self被块保留。

由于if (self)编译器的线索self可能为 nil,self因此块的隐式保留可能会导致空指针取消引用。

要修复,请检查 nil 并提前退出:

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
于 2012-05-11T01:37:45.950 回答