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

クラス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' 経由) は、null ポインターの逆参照になります。

質問: この警告が表示される理由と、この問題を解決する方法を教えてください。これについて私にアドバイスしてください。ありがとう

4

3 に答える 3

1

すべての初期化コードを

if (self) {

}

つまり、[rxmlrRoot itertate...etcを移動します。その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
    }
}

これにより、その1つのポイントからすべてのトラフィックを制御できます。

于 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)は nil である可能性があるコンパイラの手がかりであるため、ブロックによるself暗黙的な保持selfにより、null ポインターの逆参照が発生する可能性があります。

修正するには、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 に答える