PDA

View Full Version : NSMutableArray type is changed to NSArray type




tranvutuan
Feb 5, 2012, 06:56 PM
This is a structure of my Objects

myList(NSObject): items(NSMutableArray)
|
|__item(NSObject)
| |
| |__ itemKey + itemDescription
|
|__item(NSOject)
|
|__ itemKey + itemDescription

In myList.h

@interface myList : NSObject <XMLData,NSCoding>
@property (nonatomic, copy) NSMutableArray *items;


In AppDelegate.m
@implementation AppDelegate

@synthesize window = _window;
@synthesize navigationController = _navigationController;
@synthesize myList, ;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"APPDELEGATE IS LOADED AT THE BEGINNING");
myList = [[MyList alloc] init];
NSLog(@"myList items is class of %@",NSStringFromClass([myList.items class]));

- (void) check {
NSLog(@"mylist items is class of %@",NSStringFromClass([wishlist.items class]));
}

in testClass.m

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{

[myList.items removeObjectAtIndex:indexPath.row];
[myListTableView reloadData];
NSLog(@"BEFORE check::::::::myList items is class of %@",NSStringFromClass([appDelegate.wishlist.items class]));
[appDelegate check];

}
After running the program,this is the result from the debuger

APPDELEGATE IS LOADED AT THE BEGINNING
class of items is __NSArrayM
BEFORE check::::::::myList items is class of __NSArrayM
mylist items is class of __NSArrayI

I dont know why in check method at AppDelegate.m ,myList.items is a class of __NSArrayI.
I think it have to be __NSArrayM (NSMutableArray).
Have anyone had ideas about this. Please help me if you were experiencing before.



KnightWRX
Feb 5, 2012, 08:33 PM
@property (nonatomic, copy) ... :confused:

Try retain just for kicks.

tranvutuan
Feb 5, 2012, 08:48 PM
@property (nonatomic, copy) ... :confused:

Try retain just for kicks.

Can you give me an explanation for that please..

KnightWRX
Feb 5, 2012, 09:01 PM
Did it work ? From the documentation :

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
Setter Semantics

These attributes specify the semantics of a set accessor. They are mutually exclusive.
[...]
copy
Specifies that a copy of the object should be used for assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid only for object types, which must implement the NSCopying protocol.
[...]
retain
Specifies that retain should be invoked on the object upon assignment.
The previous value is sent a release message.
In OS X v10.6 and later, you can use the __attribute__ keyword to specify that a Core Foundation property should be treated like an Objective-C object for memory management:
@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

NSMutableArray inherits its NSCopying support from NSArray, and thus probably doesn't reimplement the copy method, which thus would obviously return an NSArray type instead of NSMutableArray :

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
Conforms to
NSCoding (NSArray)
NSCopying (NSArray

That's speculation on my part, haven't tried it myself.

tranvutuan
Feb 5, 2012, 09:56 PM
Did it work ? From the documentation :

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html


NSMutableArray inherits its NSCopying support from NSArray, and thus probably doesn't reimplement the copy method, which thus would obviously return an NSArray type instead of NSMutableArray :

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html


That's speculation on my part, haven't tried it myself.
I did made a change and it is working now. I am trying to convinced my self like below :
in commitEdittingStyle after doing an assignment
appDelegate.wishlist.items = wishList.items;
wishList.items on the left will be released. Moreover,"NSMutabeArray inherits from NSCopying from NSArray". Therefore, at the end appDelegate.wishlist.items is NSArray
Please correct me if I have just made a mistake... Thanks

KnightWRX
Feb 6, 2012, 08:34 AM
Like I said, speculation on my part, I have never had to do something of the sort. Try to experiment with it, changing the setter attributes and see what it does.

dejo
Feb 6, 2012, 09:24 AM
copy returns an immutable copy. If you want a mutable copy use, ...wait for it..., mutableCopy.

KnightWRX
Feb 6, 2012, 09:52 AM
copy returns an immutable copy. If you want a mutable copy use, ...wait for it..., mutableCopy.

How do you do that through properties though ? In the documentation, setter attributes cannot be mutableCopy.

dejo
Feb 6, 2012, 10:10 AM
How do you do that through properties though ? In the documentation, setter attributes cannot be mutableCopy.

Hmm, good question. I'm not sure (currently).

EDIT:

Seems the answer is to either use retain or use your own setter, like suggested here (http://stackoverflow.com/a/3220799).

The real concern seems to be justifying the need for a copy in the first place.