2013-05-31 48 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