Search code examples
objective-cmultithreadingclasswatchkitnsthread

WatchKit issue retaining data between classes


I have two classes named InterfaceController and LoadInterfaceController.

I'm fetching information in the LoadInterfaceController that I wish to pass-on to a variable in my InterfaceController class.

LoadInterfaceController:

- (void)fetchData {
    NSArray *database = //fetched information
    //... on fetch complete
    InterfaceController *interfaceController = [InterfaceController alloc];
    [interfaceController initilizeDatabase:database];
}

InterfaceController:

@property (nonatomic) NSArray *db;

- (void)initilizeDatabase:(NSArray *)database {
    self.db = database;

    NSLog(@"database count: %d", database.count); //: 3
    NSLog(@"db count: %d", self.db.count); //: 3

    [self utilizeInformation];
}

- (void)utilizeInformation {
    NSLog(@"db count: %d", self.db.count); //: 0
    //...
}

db's information is not retained outside of the initilizeDatabase: function.

I have tried running it on the main thread (as explained here), but the information is still not retained. How may I specify the thread to pass-on the information from my second class?


Solution

  • There are no problems with the threads or retention, everything is right from this perspective. But there is another issue: when you initialise the InterfaceController programmatically you create an instance of it and the db property is perfectly stored until your Watch loads it again, because Watch creates another instance of InterfaceController on its own as a result you get the empty db property on a new instance.

    The solution I'd suggest here is to add a model entity into your architecture that will act as a singleton class and it ensures your data always will be available.

    Here is an implementation considering your example:

    XYZDataBaseManager:

    @interface XYZDataBaseManager : NSObject
    
       + (nonnull XYZDataBaseManager *)sharedInstance;
    
       - @property (nonnull, strong) NSMutableArray *data;
    
    @end
    
    
    @implementation XYZDataBaseManager
    
    + (XYZDataBaseManager *)sharedInstance {
        static dispatch_once_t once;
        static XYZDataBaseManager *instance;
        dispatch_once(&once, ^{
            instance = [[XYZDataBaseManager alloc] init];
        });
        return instance;
    }
    
    @end
    

    LoadInterfaceController:

    - (void)fetchData {
        NSArray *database = //fetched information
        [XYZDataBaseManager sharedInstance].data = database;
    }
    

    InterfaceController:

    @property (nonatomic) NSArray *db;
    
    - (void)utilizeInformation {
        NSLog(@"db count: %d", [XYZDataBaseManager sharedInstance].data.count]);
    }
    

    Of course there are a lot of things to improve but I think the main idea is clear. And also I didn't execute this code so there might be some typos (I'm more swift-oriented).