2013-05-31 23 views
6

设置在另一个对象上的属性(dataControllerBWMasterViewController)中的数组的关键字带有强引用变为null。我不明白为什么。具有强引用的对象属性变为空

BWMasterViewController

头:

#import <UIKit/UIKit.h> 

@class BWBirdSightingDataController; 

@interface BWMasterViewController : UITableViewController 
@end 

实现:

#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

头:

#import <Foundation/Foundation.h> 

@class Bird; 

@interface BWBirdSightingDataController : NSObject 
- (NSUInteger)countOfList; 
- (Bird *)objectInListAtIndex:(NSUInteger)theIndex; 
@end 

实现:

#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 

鸟是NSManagedObject根据CoreData实体。

头:

#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 

实现:

#import "Bird.h" 


@implementation Bird 

@dynamic date; 
@dynamic name; 
@dynamic location; 
@dynamic image; 
@dynamic url; 

@end 

输出

当我运行它,这个输出:

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) 

因此,大家可以看到,在viewDidLoad函数bird.name已经变为null。怎么来的?我宣布财产是一个强有力的参考。

我有同样的问题,当我在viewDidLoad中定义self.dataController时,那么它将在prepareForSegue为空,在那里我也需要它。

+0

显示您的BWBirdSightingDataController代码 –

+1

@AtilaH添加它 – rednaw

+0

添加更多日志记录或使用调试器来遍历代码。经常检查'self.birds'是否不是零。我怀疑整个阵列变得无效。 – Till

回答

8

使用本地BWDataController *dataControllerinitializeDefaultDataList中创建Bird对象。 dataController会在此方法结束时自动释放,这可能意味着托管对象上下文dataController.managedObjectContext也不再存在。

但是,托管对象只能存在于其创建的上下文中。如果上下文被销毁,那么恰好会发生这种情况:访问所有属性返回nil

可能的解决方案:

  • dataControllerBWBirdSightingDataController而不是一个局部变量强大的属性。
  • 跨应用程序使用共享托管对象上下文。
+0

好吧,够公平的。那么,我怎样才能保留这些'鸟'对象在我的'鸟'属性中?我在想,我可以通过BWBirdSightingDataController管理与Core Data的通信,在内部安全地保存所需的数据并将其提供给BWMasterViewController。我会怎么做呢? – rednaw

+0

@rednaw:查看更新的答案。 –

+0

是的,我把'dataController'作为一个强大的属性,现在它可以工作!谢谢! – rednaw