Steven Ritchie
Steven Ritchie

Reputation: 228

NSNotificationCenter sending selector to the wrong instance

I am getting a very strange error while using NSNotificationCenter.

In my PersistentStack class, a subclass of NSObject, I am subscribing to three notifications:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesDidChange:", name: NSPersistentStoreCoordinatorStoresDidChangeNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesWillChange:", name: NSPersistentStoreCoordinatorStoresWillChangeNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "persistentStoreDidImportUbiquitousContentChanges:", name: NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: nil)

When these selectors are called however as a response to a notification being posted, I get a variety of different errors such as

[__NSCFArray storesDidChange:]: unrecognized selector sent to instance 0x166197f0
[NSFetchedResultsController storesDidChange:]: unrecognized selector sent to instance 

I am confused as to why other objects are getting the selector, not the object I am registering it to.

Any insight/help would be greatly appreciated!

Thanks,

-Steven

EDIT: More code for context.

AppDelegate

var persistentStack : PersistentStack { 
    return PersistentStack(storeURL: self.storeURL(), modelURL: self.modelURL())
}

PersistentStack

init(storeURL : NSURL, modelURL : NSURL) {

    super.init()

    self.storeURL = storeURL
    self.modelURL = modelURL
    setupManagedObjectContext()

}    

func setupManagedObjectContext() {

    self.managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
    self.managedObjectContext!.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    self.managedObjectContext!.persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel!)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesDidChange:", name: NSPersistentStoreCoordinatorStoresDidChangeNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesWillChange:", name: NSPersistentStoreCoordinatorStoresWillChangeNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "persistentStoreDidImportUbiquitousContentChanges:", name: NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: nil)

    var error : NSError?

    self.managedObjectContext!.persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType
        , configuration: nil, URL: self.storeURL, options: [NSPersistentStoreUbiquitousContentNameKey : "iCloudStore"], error: &error)

    if (error != nil) {
        NSLog("Error: \(error)")
    }
}

Upvotes: 0

Views: 476

Answers (2)

utahwithak
utahwithak

Reputation: 6325

NSNotificationCenter doesn't retain it's targets, this leads to errors where it will send a message to an object that has been deallocated. It sounds like you are not removing the object from NSNotificationCenter on deinit and another object (NSArray in this case) just happens to be occupying that space and receiving the messages intended for the now released object.

To remove the object from NSNotificationCenter:

NSNotificationCenter.defaultCenter().removeObserver(self)

I would place that in your deinit and put a breakpoint on it to see if that is the case.

Upvotes: 3

ugur
ugur

Reputation: 842

Because your PersistentStack instance is released by ARC. We can't help more without seeing more code (especially the code where PersistentStack instance is created and kept).

Upvotes: 0

Related Questions