Count 16

Discussion in 'Mac Programming' started by Miglu, Mar 5, 2011.

  1. Miglu macrumors member

    Joined:
    Jan 22, 2010
    #1
    I save an NSMutableArray using
    Code:
    [manager createFileAtPath:[NSString stringWithFormat:@"%@/%@", [url path], [savePanel nameFieldStringValue]] contents:[NSData dataWithBytes:nodes length:sizeof(*nodes)] attributes:nil]
    I open it using this:
    Code:
    	NSData* data;
    		if(!(data = [manager contentsAtPath:[url path]])){
    			NSLog(@"Error was code: %d - message: %s", errno, strerror(errno));
    			return;
    		}
    		nodes = [data bytes];
    		NSLog(@"%i\n", [nodes count]);
    Whatever nodes' original count is, it is 16 when I open it, and its contents have been destroyed. What is the problem?
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Why convert to/from NSData? Are you using non-plist compatible objects in the array? If so how are they converted to/from NSData?
     
  3. Miglu thread starter macrumors member

    Joined:
    Jan 22, 2010
    #3
    The array contains NSDatas that contain C structs. What would be a better way?
    [nodes addObject: [NSData dataWithBytes:node length:sizeof(*node)]];
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Probably not if you want to use a NS* class to save the structs. Simply opening the file using low-level C and saving/loading the structs using the normal C techniques might work. In all honesty the NSMutableArray options is really designed for objects.

    In all of this code what is nodes? A pointer to NSMutableArray? If so simply using that as a pointer to memory that you can save/load as a bunch of bytes is not likely to work. The basic reason for this is that internally NSArray/NSMutableArray contains further pointers. Some of these are NSObject related (isa, super etc). These might work on reload. They might not. I can't comment if those sort of things always load to the same memory location. But there will be at least one more pointer: the pointer to the underlying C array. The has to be a pointer, not a fixed size array as the size of the array varies per instance. So when you save the bytes of the NSMutableArrayObject you save something like this (all addresses made up)

    Code:
    void *isa -> 0x1234567
    void *super -> 0x0001234
    void *array -> 0x66667777
    
    That is all you are saving: you are not saving the memory area pointed to by array. When you reload the bytes you get exactly that back. isa and super might still be valid. array is now pointing at a block of memory that could realistically contain anything. I suspect the actual implementation has more pointers/layers than this but the basic problem is the same.

    Finally onto a solution. The NSCoding protocol is designed to solve this problem: it lets you turn objects into bytes to save/load. NSArray supports NSCoding so you can use it. If I were you I'd read the Archives and Serializations Programming Guide.
     
  5. Miglu thread starter macrumors member

    Joined:
    Jan 22, 2010
    #5
    I should use NSArray's encodeWithCoder. However, the section about Structures and Bit Fields explains that I should customize an archiver in order to archive the fields independently. This is an example in http://developer.apple.com/library/...ng.html#//apple_ref/doc/uid/20000949-BABGBHCA about creating an archiver:
    Code:
    NSMutableData *data;
    
    data = [NSMutableData data];
    archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    // Customize archiver here
    [archiver encodeObject:myMapView forKey:@"MVMapView"];
    [archiver finishEncoding];
    Could you explain how to archive the structs' fields?
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    All I can tell you is what the documentation says:

     
  7. Miglu thread starter macrumors member

    Joined:
    Jan 22, 2010
    #7
    Could you give an example of archiving a struct's field.
     
  8. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    No. I very rarely do examples as people just copy and paste them without understanding what they are doing.
     

Share This Page