所以我创建了一个简单的UITableViewController
,我将其推到NavigationController
。
我创建了一个initWithPList
方法,用于读取plist
并将值存储到NSMutableDictionary
items
@property
中的class
Settings
1}}。
NSMutableDictionary
方法中正确填充了initWithStyle
。但在viewDidLoad
中,NSMutableDictionary
items
的{{1}} @property
Settings
为NSObject
。
我不确定我做错了什么想法????
以下是一些代码:
显示 nil
:
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
答案 0 :(得分:2)
@synthesize items;
通过这种方式合成,属性的支持ivar名为items
。所以当你说
items = [NSMutableDictionary dictionaryWithContentsOfFile:path];
你直接分配给了伊娃。在ARC之前的手动内存管理中,任何对ivar的直接操作都与“retain”属性无关。在伊娃的水平上保留/释放完全取决于你。
现在因为您通过调用+dictionaryWithContentsOfFile:
创建字典,字典是自动释放的。所以你给了一个持久变量(items
ivar)一个瞬态对象。噗,它消失了!
解决方案是取得字典的所有权。一些便利方法没有非自动释放等效方法,因此我们必须向它们添加retain
。但在这种情况下,有一个等效的初始化器:
items = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
您拥有所有权。问题解决了。 (这也避免了向自动释放池添加任何内容。)
<强>附加:强>
对于与该物业同名的伊娃而言,这仍然是令人困惑的危险。当你看到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,更改合成以使用与ivar略有不同的名称:
@synthesize items = _items;
然后initWithPlist
可以说
_items = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
下划线提醒人们:“这就是伊娃!内存管理是你的问题!” (所以,你在release
方法中尽职地dealloc
。