ARC引起我的痛苦

时间:2013-10-08 18:55:52

标签: ios objective-c xcode automatic-ref-counting

我意识到有教程,但它们似乎永远不够深入。

现在,我有一个允许开具发票的应用。但是,由于数据类型的动态特性,我将其保留为主用户类中的sharedObject,而不是自己的类。每张发票都包含在NSMutableDictionary中,可以包含尽可能多的成员对象。有很多不同类型的发票我们发现最好这样做。

我们现在遇到的问题是,当一张发票完成,另一张已创建时,这些商品的用户界面似乎保留了以前的发票价值,即使在发票末尾,我也将NSMutableDictionary设置为为零。

基本过程:通过不同顺序的多个视图控制器,我将输入NSTextFields的值设置为NSStrings作为主NSMutableDictionary中键的值,并移动到下一个适当的屏幕。

这些NSTextFields被声明为非原子的,强大的。

他们的值设置为

[myNSMutableDictionary addObject:textField.value forKey:@"thisValue"];

因为ARC,没有任何明确的释放,我已经小心不要分配和初始化任何东西。

每个屏幕onDidShow都会在NSMutableDictionary中为文本字段指定各自的值。

我的期望是,在当前发票期间,没有文本字段将包含旧值,并且在成功将发票提交到云服务后,整个发票将被清空。切勿存放在设备中(背景除外)。

我将NSMutableDictionary设置为nil得到的结果是,屏幕似乎保留了以前的值,有时为零,但通常是前一张发票的值。

是否有一种方便的方法可以将所有成员设置为nil,或者我应该:

在我的sharedManager中将NSMutableDictionary声明为nonatomic,strong为强,在我想要一个新发件时将Alloc / Init声明为NSMutableDictionary,但将所有IBOutlets声明为非原子,弱(如此指定)在一个方向或另一个方向不保留),并确保如果我确实需要分配一个要添加到NSMutableDictionary的对象,它们被声明为某种方式也弱?例如,我需要在NSMutableDictionary,I

中存储NSArray
[myArray alloc] initWithObjects:value1, value2, nil]];

我所说的是,即使我将发票设置为nil,value1和value2似乎也是僵尸,但在第二次传递代码后重新分配。


示例代码: 在User.h中,我有一个属性:

@property (nonatomic, strong) NSMutableDictionary *currentInvoice;

在User.m中,我在'init'方法中实例化:

currentInvoice = [[NSMutableDictionary alloc] initWithCapacity:1];

创建新发票时(在InvoiceViewController.m中):

User *userInfo = [User sharedManager];
userInfo.currentInvoice = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   _clientId, @"clientId",
                                   _clientType, @"clientType",
                                   _txtClientName.text, @"clientName",
                                   keyContactName, @"keyContactId",
                                   orderTypeNum, @"orderType",
                                   _keyContact.text, @"keyContact",
                                   _problemDescription.text, @"problemDescription",
                                   _dateOfService.text, @"startDate",
                                   _startTime.text, @"startTime",
                                   _endTime.text, @"endTime", nil];

(顺便说一句,我认为我解决了我的问题,因为我从未重新实例化一个新的userInfo.currentInvoice,只是复制旧版本,这里没有提到的成员可能仍然很明确)

在InvoiceViewController.m的其他地方,一种基本取消发票流程的方法:

- (IBAction) dismissViewController:(id)action: {
     User *userInfo = [User sharedManager];
     userInfo.currentInvoice = nil;
}

在InvoiceStepTwoViewController.m中,另一个控制器与同一发票的其他方面:

@property (strong, nonatomic) IBOutlet UILabel *clientName; // in the .h, of course
@property (strong, nonatomic) IBOutlet UITextView *textView; // in .h, used to capture data

- (void)viewDidAppear {
    User *userInfo = [User sharedManager];        
    _clientName.text = [userInfo.currentInvoice objectForKey:@"clientName"];
}

经过一些改变和捕捉价值后,

- (IBAction)finishStepTwo:(id)sender {
    [userInfo.currentInvoice addEntriesFromDictionary:[NSDictionary dictionaryWithObjectsAndKeys:_textView.text, @"nerdspeak", nil]]; // so that NSMutableDictionary.currentInvoice objectForKey:@"nerdspeak" will contain _textView.text's value... but will currentInvoice own this object now? Will invoiceStepTwoViewController retain this as long as is possible?
}

我的问题;是我的viewControllers(还有更多)由于@property(强,非原子)而无意中保留值,并且从不放手(因为似乎从未调用viewDidUnload),这就是为什么数据似乎不会重新启动,或者是因为当我添加新发票时,我实际上并没有重新复制,只是复制其他值?

1 个答案:

答案 0 :(得分:2)

如果没有太多代码,看起来这与ARC没有任何关系,因此修改@property声明(即strongweak)将不会产生任何影响。

听起来您填充UI的“数据源”是NSMutableDictionary。听起来您将此词典设置为nil,然后将其分配给包含新发票数据的新NSMutableDictionary。这听起来很稳固。

但是,更改NSMutableDictionary的值不会自动修改您的UI元素的值(例如self.textLabel.text)。您需要一个与UITableView reloadData方法类似的方法,因为您在更新数据源(即字典)时调用它,并且它会相应地管理更新UI。

所以,这似乎与ARC无关,但与UILabel等对象的自然行为有关。

希望这会有所帮助......