NSKeyedArchiver 为 UIView 的子视图返回 nil

Posted

技术标签:

【中文标题】NSKeyedArchiver 为 UIView 的子视图返回 nil【英文标题】:NSKeyedArchiver returning nil for UIView's subviews 【发布时间】:2012-06-19 05:28:16 【问题描述】:

我有一个 ViewController,在此我添加了一个名为 DrawingView 的自定义 UIView。我想在这个 DrawingView 中添加 UITextView 的动态数量,所以我将 UITextView 子类化为类名为 CustomTextView。在 ViewController 中,我有以下代码将 textview 添加到 DrawingView。

- (void)viewDidLoad

    [super viewDidLoad];
    DrawingView * newDrawingView = [[DrawingView alloc]init];
    self.drawingView = newDrawingView ;


-(void)setDrawingView:(DrawingView *)_drawingView
  
    if (drawingView != _drawingView)
            
        [drawingView removeFromSuperview];
        drawingView = _drawingView;
        drawingView.customDelegate = self;
        drawingView.frame = scrollView.bounds;    
        drawingView.layer.cornerRadius = 8;
        drawingView.backgroundColor = [UIColor whiteColor];
        drawingView.clipsToBounds = YES;

        [self.view addSubview:drawingView];
    

在按钮操作上,我在绘图视图中添加了 CustomTextView。

currentText = [[TextViewContainer alloc]init];
[drawingView currentText];

现在我想归档此 DrawingView 及其子视图,即 CustomTextView。 所以在 CustomTextView 我添加了 NSCoding 协议并在其中添加了属性

- (id)initWithCoder:(NSCoder *)aDecoder

     if ((self  =  [super initWithCoder:aDecoder]))
     
         self.layer.borderWidth  =  [aDecoder decodeFloatForKey: @"borderWidth"] ;
     


- (void)encodeWithCoder:(NSCoder *)aCoder

    [aCoder encodeFloat:self.layer.borderWidth forKey:@"borderWidth"];

上述方法中还有其他自定义属性。 对于存档,我使用以下方法。

- (NSData *)dataForView:(UIView *)view:(NSString *)fileName


    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver  *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:view forKey:fileName];
    [archiver finishEncoding];

    return (id)data;



-(void)saveChangesInFile :(NSString *)fileName

    NSData *data = [self dataForView:drawingView:fileName];

    NSString *docsDirectory  =  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *dataPath  =  [docsDirectory stringByAppendingPathComponent:@"/.hidden"];

    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
    
        [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil];
    

    NSString *pathes  =  [dataPath stringByAppendingPathComponent:fileName];

    [data writeToFile:pathes atomically:YES];



- (UIView *)viewForData:(NSData *)data:(NSString*)key

    NSKeyedUnarchiver  *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

    UIView *view = [unarchiver decodeObjectForKey:key];

    [unarchiver finishDecoding];

    return view;


-(void)openSavedFileWithName:(NSString*)fileName

    NSString *docsDirectory  =  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *dataPath  =  [docsDirectory stringByAppendingPathComponent:@"/.hidden"];
    NSString *filepath = [dataPath stringByAppendingFormat:@"/%@",fileName];
    NSData *data = [NSData dataWithContentsOfFile:filepath];

    if (data)
        
        UIView *newDrawView = [self viewForData:data:fileName];
    
    NSLog(@"neew :%@",newDrawView.subviews);
    self.drawingView = (DrawingView *)newDrawView ;
    NSLog(@"self.drawingView :%@",self.drawingView.subviews);

但我得到的子视图数组为零。谁能帮帮我。

【问题讨论】:

【参考方案1】:

认为您正在尝试归档视图本身。

[archiver encodeObject:view forKey:fileName];

我认为这是错误的。您不能归档任何 UI 组件,但只能归档模型。 例如,您可以将模型(包括特定视图的大小、颜色和背景图像)保存到数据库中,但不能将视图本身保存到数据库中。同样对于存档,您需要存档其数据(即、数组、图像等),而不是 UI 组件本身。

查看the NSKeyedArchiver ClassReference 了解更多详情。 另外,请查看the link了解详细说明。 谢谢。

【讨论】:

以上是关于NSKeyedArchiver 为 UIView 的子视图返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UIDocumentPickerViewController 导入限制为 .archive 文件? (NSKeyedArchiver)

NSKeyedArchiver 保存啥格式?

在 UserDefaults 上使用 NSKeyedArchiver 时属性重置

NSData 从 NSKeyedArchiver 到 NSString

如何在新版本上转换 NSKeyedArchiver 对象

IOS 数据存储(NSKeyedArchiver 归档篇)