0

所以我创建了一个简单UITableViewController的推到NavigationController. 我创建了一个initWithPList方法,该方法读取 aplist并将值存储到NSMutableDictionaryin a 中的items @propertyaclassSettings

在方法NSMutableDictionary中正确填充initWithStyle。但在viewDidLoad,是NSMutableDictionary items @property的。Settings NSObjectnil

我不确定我在做什么错任何想法????

这是一些代码:

显示 ViewController

TestViewController *settingsViewController = [[TestViewController alloc] initWithStyle:UITableViewStyleGrouped]; 
[[self navigationController] pushViewController:settingsViewController animated:YES]

初始化 TestViewController

- (id)initWithStyle:(UITableViewStyle)style{
    
       if (self = [super initWithStyle:style]) {
                
           // Init settings property here
           settings = [[Settings alloc] initWithPList];
           // settings.items has a count of 5 here....which is correct
       }
       return self;
  }

viewDidLoad 为了 TestViewController

- (void)viewDidLoad
{
     [super viewDidLoad];
      
      // Check settings object here to see if it still has items

      // settings.items is nil here for somereason??

      NSLog(@"%i", [settings.items count]); // now it's nil here?
    
 }

Settings NSObject_

#import <Foundation/Foundation.h>

@interface Settings : NSObject {

    NSMutableDictionary *items;
    NSString *path;
}

@property(nonatomic, retain) NSMutableDictionary *items;
@property(nonatomic, retain) NSString *path;

-(id)initWithPList;

@end

的片段 @implementation

@synthesize items;
@synthesize path;

-(id) initWithPList {

    path = [[self documentsDirectory]stringByAppendingPathComponent:@"Settings.plist"];

    if(![[NSFileManager defaultManager]fileExistsAtPath:path])
    {
        [[NSFileManager defaultManager]copyItemAtPath:[[NSBundle mainBundle]pathForResource:@"Settings" ofType:@"plist"] toPath:path error:nil];
    }

    items = [NSMutableDictionary dictionaryWithContentsOfFile:path];   
    return self;  
}
4

1 回答 1

2
@synthesize items;

通过这种方式合成,该属性的支持 ivar 被命名为items. 所以当你说

    items = [NSMutableDictionary dictionaryWithContentsOfFile:path];

您直接分配给 ivar。在 ARC 之前的手动内存管理中,对 ivar 的任何直接操作都与“保留”属性无关。在 ivar 级别保留/释放完全取决于您。

现在因为您正在通过调用创建字典+dictionaryWithContentsOfFile:,所以字典是自动释放的。所以你给了一个持久变量(itemsivar)一个瞬态对象。噗,没了!

解决方案是取得字典的所有权。一些方便的方法没有非自动释放等价物,所以我们必须retain给它们添加一个。但在这种情况下,有一个等效的初始化程序:

    items = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

你拥有所有权。问题解决了。(这也避免了向自动释放池添加任何内容。)

额外: 对于与财产同名的 ivar,这仍然是令人困惑的危险。每当您看到 时,很容易误以为您正在获取属性的属性items。首先,让我们摆脱 ivars 的显式声明。属性不需要它们。

@interface Settings : NSObject

@property(nonatomic, retain) NSMutableDictionary *items;
@property(nonatomic, retain) NSString *path;

- (id)initWithPList;

@end

Apple 的惯例是在 ivars 前加上下划线。如果您使用的是 Xcode 4.5,只需@synthesize完全省略该语句即可。对于早期的 Xcode,更改 synthesize 以使用稍微不同的 ivar 名称:

@synthesize items = _items;

然后initWithPlist可以说

    _items = [[NSMutableDictionary alloc] initWithContentsOfFile:path];

下划线作为提醒:“这是 ivar!内存管理是你的问题!” (所以,你releasedealloc方法中尽职尽责。)

于 2012-11-24T18:14:41.850 回答