【问题标题】:Recreating NSMutableArray重新创建 NSMutableArray
【发布时间】:2014-06-11 14:09:49
【问题描述】:

我有一个名为 _objects 的 NSMutableArray,存储在 NSUserDefaults 中。我在应用程序启动时访问 _objects 并将它们放在带有自定义单元格的 CollectionView 中(见下文)。我让用户首先进入编辑模式然后点击所需的单元格来编辑每个项目。然后单元格类相应地改变视觉外观并显示一个 UITextField。每当用户在此处输入数据时按下键盘上的完成,ProjectsViewController (CollectionView viewcontroller) 就会从自定义类获取通知以重新保存项目。那么如何保存新的 _objects 呢?

具体我需要编辑一个单元格(完成),编辑_objects中的相应项目并重新保存_objects。我怎样才能做到这一点?

我的自定义类:

ProjectCell.h:

#import <UIKit/UIKit.h>

@interface ProjectCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UILabel *projectLabel;
@property (weak, nonatomic) IBOutlet UILabel *projectCount;
@property (weak, nonatomic) IBOutlet UITextField *projectTextField;
@property (weak, nonatomic) IBOutlet UILabel *editModeLabel;
@property (nonatomic, assign) BOOL editMode;;

-(void)editProject;

@end

ProjectCell.m:

#import "ProjectCell.h"
#import "QuartzCore/CALayer.h"

@implementation ProjectCell
@synthesize editMode;

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
    // Initialization code
}
return self;
}

-(void)awakeFromNib {
// Custom initial code
[_projectTextField setDelegate:self];
[_projectTextField setReturnKeyType:UIReturnKeyDone];
[_projectTextField addTarget:self
                   action:@selector(editingFinished:)
         forControlEvents:UIControlEventEditingDidEndOnExit];
}

- (IBAction)editingFinished:(id)sender
{
// Update the project cell visually
_projectLabel.text = _projectTextField.text;
// disable editMode and update the project cell
editMode = NO;
_projectTextField.hidden = YES;
_editModeLabel.hidden = YES;

// Reload the MasterViewController
[[NSNotificationCenter defaultCenter] postNotificationName:@"saveNewProjects" object:self];
}

-(void)editProject {
if (editMode == YES) {
    // disable editMode and update the project cell
    editMode = NO;
    _projectTextField.hidden = YES;
    _editModeLabel.hidden = YES;
} else if (editMode == NO) {
    // Enable editMode and update the project cell
    editMode = YES;
    _projectTextField.hidden = NO;
    _editModeLabel.hidden = NO;
}
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/

@end

ProjectsViewController.m

只要用户在编辑单元格时按下“完成”,就会调用此方法。 我试图循环浏览每个项目并“重新创建” NSMutableArray 但我 不要认为这是一个很好的方法。

- (void)resaveProjects:(NSNotification *)notification {
// Edit the edited projects and save all again
editedProjects = editedProjects - 1;

NSMutableArray *newObjects;
int objectsCount = _objects.count;
for (int i = 0; i < objectsCount; i++) {
    // Initialize objects
    if (!newObjects) {
        newObjects = [[NSMutableArray alloc] init];
    }
}
}

您认为最好的方法是什么?我该如何进行?

谢谢!

编辑:

读取_objects:

     NSMutableArray *_objects;
    _objects = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"myProjects"]];

【问题讨论】:

    标签: ios objective-c uitableview nsmutablearray nsuserdefaults


    【解决方案1】:

    在 iOS 或 Mac OS 中,当您读取字典或数组之类的集合对象(从用户默认值或 plist 中)时,即使原始对象是可变的,该对象也会被读取为不可变的。

    因此,在从用户默认值中读取字典后,您必须将其转换为可变对象。

    我建议您从用户默认值中读取您的对象并将其转换为可变版本:

    在您的标题中:

    @property (nonatomic, strong) NSMutableDictionary *aDict;
    

    在你的 .m 文件中,当你阅读字典时:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *aDict = [[defaults objectForKey: @"aDictionaryKey"] mutableCopy];
    

    然后,当用户做了一些需要你改变数据的事情时:

    aDict[key] = newValueFromUser;
    [defaults setObject: aDict forKey: @"aDictionaryKey"];
    

    请注意,如果您的字典包含其他集合对象(数组或其他字典),则在从文件中读回时,这些对象也将变为不可变的。这意味着您可能必须遍历字典的“对象图”,将其中的每个集合转换为可变版本并将其保存在它的封闭集合中。

    我刚刚在网上找到了一些帖子,声称 NSCoding 保留了对象的可变性。如果是这种情况,那么您可能希望将字典保存到存档文件,而不是将其保存到用户默认值:

    将字典写入文件:

    NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
      NSUserDomainMask, YES) lastObject]
    NSString *path = [documentsDir stringByAppendingPathComponent: @"dictFile"];
    [NSKeyedArchiver archiveRootObject: myDict toFile: path];
    

    回读:

    NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
      NSUserDomainMask, YES) lastObject]
    NSString *path = [documentsDir stringByAppendingPathComponent: @"dictFile"];
    myDict = [NSKeyedUnarchiver unarchiveObjectWithFile: path];
    

    【讨论】:

    • 嗯,我想你误会了。我编辑了一个 CollectionViewCell,需要在 NSMutableArray 中编辑相应的一个。一种适合我现有代码的方法。我在更新的问题中读取了我的数组,如上所示
    • 查看您编辑的问题,您正在从默认值中读取 ARRAY。我以为你说你有字典?它是一个字典数组吗?如果它是一个数组,我的 cmets 仍然持有。您展示了将您读取的数组转换为可变数组的代码。因此只需替换用户更改的每个单元格的数组条目,使用setObject:forKey: 将更改的数组保存回用户默认值,然后调用用户默认值方法同步以强制保存更改。
    • 请注意,将集合视图的状态保存为用户默认值可能是对用户默认值的过度使用,您应该考虑另一种保存数据的方法(如我上面提到的 NSCoding)
    • 是的,但我的问题是获取选定的单元格并只编辑那个单元格。当用户按下完成时,我需要获取“活动”或“编辑”单元格,然后在我的数组中找到该字符串并替换它。保存和读取数组不是问题:)
    • 你怎么看? @邓肯C
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 2012-04-22
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多