Strong link object property becomes null

The array key that sets the property on another object ( dataController in BWMasterViewController ) with a strong reference becomes null . I do not understand why.

BWMasterViewController

Title:

 #import <UIKit/UIKit.h> @class BWBirdSightingDataController; @interface BWMasterViewController : UITableViewController @end 

implementation:

 #import "BWMasterViewController.h" #import "BWBirdSightingDataController.h" #import "Bird.h" #import "BWWebviewController.h" @interface BWMasterViewController() @property (strong, nonatomic) BWBirdSightingDataController *dataController; @property (copy, nonatomic) NSString *test; @end @implementation BWMasterViewController - (void)awakeFromNib { [super awakeFromNib]; NSLog(@"awake from nib"); self.dataController = [[BWBirdSightingDataController alloc] init]; self.test = @"Test var"; NSLog(@"test: %@", self.test); Bird *bird = [self.dataController objectInListAtIndex:0]; NSLog(@"bird object: %@", bird); NSLog(@"bird name: %@", bird.name) } - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"view did load"); NSLog(@"test: %@", self.test); Bird *bird = [self.dataController objectInListAtIndex:0]; NSLog(@"bird object: %@", bird); NSLog(@"bird name: %@", bird.name) } // .... 

BWBirdSightingDataController

Title:

 #import <Foundation/Foundation.h> @class Bird; @interface BWBirdSightingDataController : NSObject - (NSUInteger)countOfList; - (Bird *)objectInListAtIndex:(NSUInteger)theIndex; @end 

implementation:

 #import "BWBirdSightingDataController.h" #import "BWDataController.h" #import "Bird.h" @interface BWBirdSightingDataController () -(void)initializeDefaultDataList; @property (nonatomic, copy) NSMutableArray *birds; @end @implementation BWBirdSightingDataController - (id)init { if (self = [super init]) { [self initializeDefaultDataList]; return self; } return nil; } - (void)initializeDefaultDataList { BWDataController *dataController = [[BWDataController alloc] init]; NSEntityDescription *birdsEntity = [NSEntityDescription entityForName:@"Bird" inManagedObjectContext:dataController.managedObjectContext]; NSFetchRequest *fetchBirds = [[NSFetchRequest alloc] init]; [fetchBirds setEntity:birdsEntity]; NSError *fetchError = nil; NSArray *birdsObjects = [dataController.managedObjectContext executeFetchRequest:fetchBirds error:&fetchError]; self.birds = [birdsObjects mutableCopy]; } - (NSUInteger)countOfList { return [self.birds count]; } - (Bird *)objectInListAtIndex:(NSUInteger)theIndex { return self.birds[theIndex]; } @end 

Bird

The NSManagedObject bird is based on a CoreData object.

Title:

 #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @interface Bird : NSManagedObject @property (nonatomic, retain) NSDate * date; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSString * location; @property (nonatomic, retain) NSString * image; @property (nonatomic, retain) NSString * url; @end 

implementation:

 #import "Bird.h" @implementation Bird @dynamic date; @dynamic name; @dynamic location; @dynamic image; @dynamic url; @end 

Output

When I run it, the outputs are:

 2013-05-31 11:36:47.824 BirdWatching[69565:c07] awake from nib 2013-05-31 11:36:47.834 BirdWatching[69565:c07] test: Test var 2013-05-31 11:36:47.834 BirdWatching[69565:c07] bird object: <Bird: 0x8545ec0> (entity: Bird; id: 0x8545040 <x-coredata://D24A664F-8E8F-4AF0-891C-098C8A7DD860/Bird/p1> ; data: <fault>) 2013-05-31 11:36:47.835 BirdWatching[69565:c07] bird name: Pigeon 2013-05-31 11:36:47.839 BirdWatching[69565:c07] view did load 2013-05-31 11:36:47.840 BirdWatching[69565:c07] test: Test var 2013-05-31 11:36:47.840 BirdWatching[69565:c07] bird object: <Bird: 0x8545ec0> (entity: Bird; id: 0x8545040 <x-coredata://D24A664F-8E8F-4AF0-891C-098C8A7DD860/Bird/p1> ; data: <fault>) 2013-05-31 11:36:47.840 BirdWatching[69565:c07] bird name: (null) 

So, as you can see, in viewDidLoad function has become null. How so? I proclaimed this property a strong reference.

I have the same problem when I defined self.dataController in viewDidLoad , then it would be null in prepareForSegue , where I also need it.

+6
source share
1 answer

You create Bird objects in initializeDefaultDataList using the local BWDataController *dataController . dataController automatically freed at the end of this method, which probably means that the context of the dataController.managedObjectContext managed entity also no longer exists.

However, a managed entity can only live in the context in which it was created. If the context is destroyed, then this is exactly what happens: access to all properties returns nil .

Possible solutions:

  • Make dataController strong dataController property instead of a local variable.
  • Use the general context of managed objects in the application.
+8
source

Source: https://habr.com/ru/post/946247/


All Articles