我现在拥有的是
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;
}
警告:实例变量访问(通过'self')导致空指针取消引用
问题:为什么我收到此警告以及如何解决此问题。 请就此向我提出建议。感谢
答案 0 :(得分:1)
尝试将所有初始化代码放在
中if (self) {
}
即移动[rxmlrRoot itertate ...等。进入那个if语句
作为一般规则,所有初始化语法(init方法中的所有内容!)都应该在if(self)块中。原因是当超类返回nil时,该块外部的代码将运行(想想如果(!self){...)。如果没有调用super方法(初始化程序只是O-C中的常规方法),则不希望代码继续执行。
我还被教导在我的自定义类中总是有一个指定的初始化器(这是调用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 :(得分:0)
在电话[rxmlRoot iterate:node with:^(RXMLElement *e){ ... }]
中,什么是节点?它不是局部变量,也不是iVar。它是全球性的还是存在于其他地方?
无论如何,请检查以确保已初始化。
答案 2 :(得分: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