使用通知中心发布通知时出现 EXC_BAD_ACCESS 错误(代码 = 1)
Getting EXC_BAD_ACCESS error (code = 1) when posting a notification with Notification Center
我有一个使用这种方法的视图控制器:
- (void)getImages
{
if (self.myEntities != nil) {
if (self.myEntities.count > 0) {
if (self.imagesDownloader == nil) {
self.imagesDownloader = [[ImagesDownloader alloc] initWithListener];
}
}
for (MyEntity *myEntity in self.myEntities) {
if (![myEntity.imageUrl isEqualToString:@""] && (myEntity.imageUrl != nil)) {
[self.imagesDownloader getImageFromServiceUrl:myEntity.imageUrl];
}
}
}
}
而 ImagesDownloader
是一个 NSObject
子类,如下所示:
@implementation ImagesDownloader
- (id)initWithListener
{
self = [super init];
if (self) {
[self registerNotifications];
}
return self;
}
- (void)registerNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"getImageDidFinish"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getImageDidFinish:)
name:@"getImageDidFinish"
object:nil];
}
- (void)getImageFromServiceUrl:(NSString *)imageUrl
{
GetImage *getImage = [[GetImage alloc] init];
[getImage queryServiceWithImageUrl:imageUrl];
}
// More instance methods
@end
反过来,GetImage
是另一个 NSObject
子类,它通过使用 NSURLConnection
对象调用 RESTful 网络服务,然后,在其 connectionDidFinishLoading:
委托方法,它发布 imagesDownloader
对象正在通过通知中心观察的通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"getImageDidFinish"
object:nil
userInfo:serviceInfoDict];
这是我有时会遇到 EXC_BAD_ACCESS 错误的调用。
场景是这样的:加载视图控制器(将其推入导航堆栈)并调用 getImages
。现在,它的 self.myEntities
有 3 个对象,所以 self.imagesDownloader
被初始化并调用了 3 次 getImageFromServiceUrl
。该服务也被调用了 3 次,并且在 connectionDidFinishLoading:
中,通知发布了 3 次且没有错误。
但我随后在视图控制器中来回切换,再次加载它并进行相同的调用。但是这一次,我第二次收到错误消息,通知将从 connectionDidFinishLoading:
发布。我不明白为什么,我会错过什么?
提前致谢
正如@PhillipMills 所说,将此添加到 ImagesDownloader
似乎可以解决问题:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
我有一个使用这种方法的视图控制器:
- (void)getImages
{
if (self.myEntities != nil) {
if (self.myEntities.count > 0) {
if (self.imagesDownloader == nil) {
self.imagesDownloader = [[ImagesDownloader alloc] initWithListener];
}
}
for (MyEntity *myEntity in self.myEntities) {
if (![myEntity.imageUrl isEqualToString:@""] && (myEntity.imageUrl != nil)) {
[self.imagesDownloader getImageFromServiceUrl:myEntity.imageUrl];
}
}
}
}
而 ImagesDownloader
是一个 NSObject
子类,如下所示:
@implementation ImagesDownloader
- (id)initWithListener
{
self = [super init];
if (self) {
[self registerNotifications];
}
return self;
}
- (void)registerNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"getImageDidFinish"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getImageDidFinish:)
name:@"getImageDidFinish"
object:nil];
}
- (void)getImageFromServiceUrl:(NSString *)imageUrl
{
GetImage *getImage = [[GetImage alloc] init];
[getImage queryServiceWithImageUrl:imageUrl];
}
// More instance methods
@end
反过来,GetImage
是另一个 NSObject
子类,它通过使用 NSURLConnection
对象调用 RESTful 网络服务,然后,在其 connectionDidFinishLoading:
委托方法,它发布 imagesDownloader
对象正在通过通知中心观察的通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"getImageDidFinish"
object:nil
userInfo:serviceInfoDict];
这是我有时会遇到 EXC_BAD_ACCESS 错误的调用。
场景是这样的:加载视图控制器(将其推入导航堆栈)并调用 getImages
。现在,它的 self.myEntities
有 3 个对象,所以 self.imagesDownloader
被初始化并调用了 3 次 getImageFromServiceUrl
。该服务也被调用了 3 次,并且在 connectionDidFinishLoading:
中,通知发布了 3 次且没有错误。
但我随后在视图控制器中来回切换,再次加载它并进行相同的调用。但是这一次,我第二次收到错误消息,通知将从 connectionDidFinishLoading:
发布。我不明白为什么,我会错过什么?
提前致谢
正如@PhillipMills 所说,将此添加到 ImagesDownloader
似乎可以解决问题:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}