我有一个TableViewController,在运行时,创建另一个类的实例并用它调用json,例如。
-(void)viewDidLoad{
JSONClass *jc = [[JSONClass alloc]init];
jc.JSONClassDelegate = (id)self;
[jc view];
}
JSONClass将继续从Web检索数据,一旦完成,将向tableViewController发送委托方法调用“JSONClassDataReceived”。如,
-(void)viewDidLoad{
//codes of URL connection goes here...
NSMutableURLRequest *request = [[NSMutableURLRequest new];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:responseData waitUntilDone:YES];
}
- (void)fetchedData:(NSData *)responseData {
NSMutableDictionary *data = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:&error];
if (JSONPromotionsLocationsDelegate && [JSONPromotionsLocationsDelegate respondsToSelector:@selector(JSONPromotionsLocationsDataReceived)]) {
[JSONPromotionsLocationsDelegate JSONPromotionsLocationsDataReceived];
}
}
- (void)JSONClassDataReceived{
[tableView reloadTable];
}
之后填充相关数据。
如果在我的tableViewController上调用委托方法JSONClassDataReceived之前在TableViewController上按下后退按钮,如何停止JSONClass?
我试过
jc.JSONClassDelegate = nil;
jc = nil;
当按下后退按钮时,我的应用程序崩溃,因为JSONClass已到达JSONClassDelegate,因此无法找到方法 - (void)JSONClassDataReceived,因为tableViewController视图不再存在。我也尝试过在JSONClass中实现dealloc。似乎没有用。
- (void)dealloc{
self.view = nil;
}
我的行上有错误EXC_BAD_ACCESS,
if (JSONPromotionsLocationsDelegate && [JSONPromotionsLocationsDelegate respondsToSelector:@selector(JSONPromotionsLocationsDataReceived)]) {
[JSONPromotionsLocationsDelegate JSONPromotionsLocationsDataReceived];
}
答案 0 :(得分:9)
我似乎通过简单地将我的委托设置为弱而不是分配来修复崩溃。
@property (nonatomic, assign)id <JSONClassDelegate> JSONClassDelegate;
@property (nonatomic, weak)id <JSONClassDelegate> JSONClassDelegate;
答案 1 :(得分:2)
在向Stack Overflow发布有关崩溃的问题时,包含崩溃日志或堆栈跟踪以帮助您帮助解决问题是有帮助的。
解决EXC_BAD_ACCESS崩溃问题的正确方法是使用Zombies instrument of Instruments。这将告诉您究竟是什么导致了这个问题。
没有这些信息,我们只能猜测。
但在你的情况下,我可以采取有根据的猜测。 您的委托在某个时候被释放,之后您尝试使用释放的内存。这很可能是因为您尚未将委托声明为弱引用。 several中的points documentation专门提到了这一点。
首先,将您的委托声明为弱属性。
@property (nonatomic, weak) id JSONClassDelegate;
别忘了合成它。不合成属性会导致不好的事情。
现在,在您调用代理的方法中,您应该将其作为方法持续时间的强引用。这可以防止在您使用它时将其解除分配。例如:
__strong id aDelegate = [self JSONClassDelegate];
if ([JSONClassDelegate respondsToSelector:@selector(JSONPromotionsLocationsDataReceived)]) {
[JSONClassDelegate JSONPromotionsLocationsDataReceived];
}
这会创建一个强大的本地堆栈变量,指向您的弱引用。它将被保留,直到它超出范围。
答案 2 :(得分:1)
首先,确保在调用您的委托之前执行此操作:
if (self.delegate && [self.delegate respondsToSelector:@selector(JSONClassDataReceived)]) {
[self.delegate JSONClassDataReceived];
}
除此之外,在您的JSONClass“- (void)dealloc
方法中,您可以停止网络通话。如果您使用的是ARC,请确保不要拨打[super dealloc]
。对于要调用的dealloc
方法,您需要将jc
对象置零。
希望这有帮助。
答案 3 :(得分:1)
不,你不能(有用)“测试地址是否包含有效对象”。即使您能够在内存分配系统的内部进行内容并确定您的地址指向有效对象,这也不一定意味着它与您之前引用的对象相同:该对象可能已经存在deallocated和在同一个内存地址创建的另一个对象。
从here找到。