I found this implementation of a hash table written in objective-c. I can follow almost all of it, but am struggling to understand how exactly the -(id) init function works. This is the method in the HashTable.m file with 3 lines (I repasted it below right after the question). Could someone explain what exactly it is doing? I included some of the other relevant code although for the most part I think I can follow the rest. Despite that I'm unclear as to the specifics of the init method. Thanks
-(id)init
{
self =[super init];
self.othercontainer = [[NSMutableArray alloc]init];
return self;
}
HashTable.h
#import <Foundation/Foundation.h>
#interface HashTable : NSObject
#property(nonatomic) NSMutableArray* othercontainer;
-(id)objectForKey:(NSString*)name;
-(void)setObject:(id)object forKey:(NSString*)name;
-(id)init;
#end
HashTable.m
#import "HashTable.h"
#import "Person.h"
#implementation HashTable
-(id)init
{
self =[super init];
self.othercontainer = [[NSMutableArray alloc]init];
return self;
}
-(id)objectForKey:(NSString*)name
{
Person* tempPerson = nil;
for (id item in self.othercontainer)
{
NSString* tempName = [((Person*)item) name];
if ([tempName isEqualToString:name])
{
tempPerson = item;
break;
}
}
return tempPerson;
}
-(void)setObject:(id)object forKey:(NSString*)name
{
[self.othercontainer addObject:object];
}
#end
Part of ViewController.m
NSData *data;
NSFileHandle *fh;
NSString *inBoundFile = #"/Users/user/Desktop/names.txt";
NSString *fileString;
fh = [NSFileHandle fileHandleForReadingAtPath:inBoundFile];
data = [fh readDataToEndOfFile];
fileString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSArray *PersonArray = [fileString componentsSeparatedByString:#"\n"];
self.container = [[HashTable alloc]init];
for (int x= 0; PersonArray.count > x ;x++) {
NSArray* tempNameandAddress = [PersonArray[x] componentsSeparatedByString:#" "];
Person *personA = [[Person alloc]init]; //could be other ways of defining an instance of an object
personA.name = tempNameandAddress[0];
personA.address = tempNameandAddress[1];
if ([self.container objectForKey:personA.name] == nil)
[self.container setObject:personA forKey:personA.name];
else
NSLog(#"%# already exists \n",personA.name);
}
This is simply an almost right common init.
self is set to the object returned by the superclass init.
Then they miss one proper step.
The next step should be if (self) { ...additional setup... }
Basically only creating ivars/properties if self as returned from super init is not nil.
If self is nil at that point you would normally just bypass additional code and go straight to return self. (Returning nil)
The next line is just creating the NSMutableArray ivar for the othercontainer property.
This is also not quite right.
In init, this is when you should use the synthesized ivar directly.
_othercontainer = [[NSMutableArray alloc] init];
Nothing special here.
Related
I need to make a "clone" of an array to another, but the thing is that when I modify my copied Array, the original is modified too. Using hard copy is not working as I expect.
I'm initializing an array like this:
NSMutableArray *otherArray = [[NSMutableArray alloc] initWithArray: myList copyItems:YES];
where myList is a NSArray that came as a parameter in my function.
The thing is when I need to return myList, it's content has been modified when I modify my otherArray
I tried making a hard copy like:
NSMutableArray* algo = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:myList]];
But, some of the properties are not converted, and a nil value is assigned to them.
Also I tried with this:
NSMutableArray *otherArray = [myList mutableCopy];
Well, the obvious question is: How can I modify a copied object without modifying the original one?
Thanks!
EDIT: Here is my entire function.
RAC(self,filteredPacks) = [RACSignal combineLatest:#[self.searchBoxSignal, self.packListsSignal]
reduce:^NSArray *(NSString *filterString, NSArray *packList) {
NSMutableArray *sweetHelper = [[NSMutableArray alloc] init];
NSMutableArray* packListCopy = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject:packList]];
filterString = [filterString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([filterString length] > 0)
{
for(PackList *theList in packListCopy){
NSMutableIndexSet *indexesToDelete = [NSMutableIndexSet indexSet];
NSUInteger currentIndex = 0;
for(Pack *thePack in theList.resolved_packs){
if([thePack.name rangeOfString:filterString options:NSCaseInsensitiveSearch].location == NSNotFound){
[indexesToDelete addIndex:currentIndex];
}
currentIndex++;
}
[theList.resolved_packs removeObjectsAtIndexes:indexesToDelete];
[theList.packs removeObjectsAtIndexes:indexesToDelete];
[sweetHelper addObject:theList];
}
return sweetHelper;
}
else
{
return self.originalList;
}
}
];
Well, I found the solution using this answer and this comment in the same question.
As I said in my question:
"I tried making a hard copy like:
NSMutableArray* algo = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:myList]];
But, some of the properties are not converted, and a nil value is assigned to them."
Well, the properties that were not converted, they weren't because they are custom objects, An I didn't implemented the initWithCode and encodeWithCoder methods. So, when I added those methods to my customObjectClass, my Arrays were hard copied with all their elements.
A little example about what I did:
In my SomeCustomObject.h I should implements NSCoding:
#interface SomeCustomObject : NSObject <NSCoding> {
NSMutableArray * __packs;
int __type;
Link * __selfRef;
NSMutableArray * __resolved_packs;
}
And in my subclass of SomeCustomObject I got something like:
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
__packs = [decoder decodeObjectForKey:#"packs"];
__type = [decoder decodeIntForKey:#"type"];
__selfRef = [decoder decodeObjectForKey:#"selfRef"];
__resolved_packs = [decoder decodeObjectForKey:#"resolved_packs"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:__packs forKey:#"packs"];
[encoder encodeInt:__type forKey:#"type"];
[encoder encodeObject:__selfRef forKey:#"selfRef"];
[encoder encodeObject:__resolved_packs forKey:#"resolved_packs"];
}
I hope this be useful to somebody :)
I have created a small app with several views. For this I use the storyboard and for each view a viewcontroller. Now, I have to store data, which the user can enter on the view. I want to use a Dictionary for this. I now, how to create a dictionary:
NSMutableDictionary *globalData = [[NSMutableDictionary alloc] init];
//add keyed data
[globalData setObject:#"Object One" forKey:#"1"];
[globalData setObject:#"Object Two" forKey:#"2"];
I am searching now the right place to add and instantiate this dictionary, that it can be used as model in all views.
You can use a singleton model object to keep the global data. If you are using this in almost all viewControllers declare in *.pch file. If you are using dictionary you define some constants for ease of use.
GlobalDataModel *model = [GlobalDataModel sharedDataModel];
//Pust some value
model.infoDictionary[#"StoredValue"] = #"SomeValue";
//read from some where else
NSString *value = model.infoDictionary[#"StoredValue"];
.h file
#interface GlobalDataModel : NSObject
#property (nonatomic, strong) NSMutableDictionary *infoDictionary;
+ (id)sharedDataModel;
#end
.m file
#implementation GlobalDataModel
static GlobalDataModel *sharedInstance = nil;
- (id)init{
self = [super init];
if (self) {
self.infoDictionary = [NSMutableDictionary dictionary];
}
return self;
}
+ (id )sharedDataModel {
if (nil != sharedInstance) {
return sharedInstance;
}
static dispatch_once_t pred; // Lock
dispatch_once(&pred, ^{ // This code is called at most once per app
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Declare the NSMutableDictionary as a property in .h file for all ViewControllers concerning the model
In your .m file, implement the getter of the NSMutableDictionary using lazy instantiation.
..
-(NSMutbaleDictionary *) globalData{
if (_globalData == nil){
_globalData = [[NSMutableDictionary alloc]init];
}
return _globalData;
}
transfer the dictionary to other viewControllers of other views in prepareForSegue:
The goal, to create a class which contains an array of data to be used throughout the application by other classes.
I have this GlobalObject.h
It declares the array to be used to store the data.
#import <Foundation/Foundation.h>
#interface GlobalObjects : NSObject
#property (retain) NSMutableArray *animals;
-(id)init;
#end
I have this GlobalObject.m.
It contains the NSDictionary data and stores in to the array.
#import <Foundation/Foundation.h>
#interface GlobalObjects : NSObject
#property (retain) NSMutableArray *animals;
-(id)init;
#end
#import "GlobalObjects.h"
#implementation GlobalObjects
#synthesize animals;
-(id)init{
self = [super init];
if (self) {
// Define the data
NSArray *imagesValue = [[[NSArray alloc] initWithObjects:#"dog.wav",#"cat.png",#"bird.png",nil] autorelease];
NSArray *audioValue =[[[NSArray alloc] initWithObjects:#"dog.wav",#"cat.wav",#"bird.wav",nil] autorelease];
NSArray *descriptionValue = [[[NSArray alloc] initWithObjects:#"Dog",#"Cat",#"Bird",nil] autorelease];
// Store to array
for (int i=0; i<8; i++) {
NSDictionary *tempArr = [NSDictionary dictionaryWithObjectsAndKeys:[imagesValue objectAtIndex:i],#"image", [audioValue objectAtIndex:i],#"audio", [descriptionValue objectAtIndex:i], #"description", nil];
[self.animals addObject:tempArr];
}
}
return self;
}
#end
Here's how I call it.
// someOtherClass.h
#import "GlobalObjects.h"
#property (nonatomic, retain) GlobalObjects *animalsData;
// someOtherClass.m
#synthesize animalsData;
self.animalsData = [[[GlobalObjects alloc] init] autorelease];
NSLog(#"Global Object %# ",self.animalsData.animals);
Now the problem is, when I call this array in another class, it always returns null.
I'm new to iOS programming. So probably my method is wrong?
You forgot to allocate the animals array in the init method of "GlobalObjects":
self.animals = [[NSMutableArray alloc] init];
If you don't do this, self.animals is nil and addObject has no effect.
Since you do not use ARC, remember to release the array in dealloc.
EDIT: As #H2CO3 and #Bastian have noticed, I forgot my pre-ARC lessons. So the correct way to allocate self.animals in your init method is
self.animals = [[[NSMutableArray alloc] init] autorelease];
and in dealloc you have to add
self.animals = nil;
before calling [super dealloc]. I hope that I got it right now!
Yes, it's wrong - an instance variable isn't tied to a class itself, but to a particular instance of the class. The Cocoa-standard solution to this problem is creating a shared instance of the class - instead of
elf.animalsData = [[[GlobalObjects alloc] init] autorelease];
write
elf.animalsData = [GlobalObjects sharedInstance];
and implement the + sharedInstance method like this:
+ (id)sharedInstance
{
static shared = nil;
if (shared == nil)
shared = [[self alloc] init];
return shared;
}
As #MartinR pointed out, you make another mistake: you don't create the array you're adding objects to - then it remains nil, cancelling out the effect of all method calls on itself. You have to alloc-init a mutable array for it in the - init method.
I'm writing some code for an iPhone app, and I'm having issues getting default data to load in correctly. I am basing my code off some example from the "Learning Cocos2d" book by Ray Wenderlich.
It seems that even when I delete the app outright and try to start from fresh data that the app inconsistently either doesn't try to load the data, or incorrectly thinks that there is data, and loads null.
I'm using containsValueForKey to check if a value exists and then load it or load some default value, but even on a fresh installation the containsValueForKey finds data and doesn't load the defaults. In xcode's organizer I checked my device's file structure and the Documents folder, where I specified to save, doesn't look like it contains any files, so I'm not sure what it's grabbing.
My guess is that the problem is something to do with the initWithCoder function. It seems to mysteriously go through the function sometimes, but not all the time. Another weird thing is that I call [[GameManager sharedGameManager] save] when the player gets a highscore (not shown here, but the code is the exact same as this objectiveList, only an int) and it appears to save it correctly.
And now the code:
GCDatabase.h
#import <Foundation/Foundation.h>
id loadData(NSString * filename);
void saveData(id theData, NSString *filename);
GCDatabase.m
#import "GCDatabase.h"
NSString * pathForFile(NSString *filename) {
// 1
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
// 2
NSString *documentsDirectory = [paths objectAtIndex:0];
// 3
return [documentsDirectory stringByAppendingPathComponent:filename];
}
id loadData(NSString * filename) {
NSString *filePath = pathForFile(filename);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
id retval = [unarchiver decodeObjectForKey:#"Data"];
[unarchiver finishDecoding];
return retval;
}
return nil;
}
void saveData(id theData, NSString *filename) {
NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
[archiver encodeObject:theData forKey:#"Data"];
[archiver finishEncoding];
[data writeToFile:pathForFile(filename) atomically:YES];
}
GameManager.h
#interface GameManager : NSObject <NSCoding>{
NSMutableArray *objectiveDescriptions;
}
#property (nonatomic, retain) NSMutableArray * objectiveDescriptions;
+(GameManager*)sharedGameManager;
-(void)save;
-(void)load;
-(void)encodeWithCoder:(NSCoder *)encoder;
-(id)initWithCoder:(NSCoder *)decoder;
#end
GameManager.m (I added the load function, in an attempt to force it to load, but it doesn't seem to work)
+(GameManager*)sharedGameManager {
#synchronized([GameManager class])
{
if(!sharedGameManager) {
sharedGameManager = [loadData(#"GameManager") retain];
if (!sharedGameManager) {
[[self alloc] init];
}
}
return sharedGameManager;
}
return nil;
}
+(id)alloc {
#synchronized([GameManager class]){
NSAssert(sharedGameManager == nil, #"Attempted to allocate a second instance of the Game Manager singleton");
sharedGameManager = [super alloc];
return sharedGameManager;
}
return nil;
}
- (void)dealloc {
[objectiveList release];
[super dealloc];
}
- (void)save {
saveData(self, #"GameManager");
}
-(void)load {
loadData(#"GameManager");
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:objectiveList forKey:#"objectiveList"];
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self != nil) {
if ([decoder containsValueForKey:#"objectiveList"]) {
objectiveList = [decoder decodeObjectForKey:#"objectiveList"];
} else {
[objectiveList addObjectsFromArray:[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil]];
}
}
return self;
}
#end
I have not read your full code.. But I found a problem in code....
You have not allocated memory to objectiveList array.. Unless and until you allocate memory to array, objects will not be added...
I think go for
objectiveList = [[NSMutableArray alloc] initWithArray:[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil]];
instead of
[objectiveList addObjectsFromArray:[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil]];
Check for the syntax.. Hope this may help as it troubled me also in the past where I forgot to allocate memory to the array.. And kept on adding objects resulting in null... :)
In case it doesn't solve your problem, I'll look for code later completely.. :)
I seem to see the problem. When the constructor is called the first time, the objectiveList is not even created as the "initWithCoder" is never called. You have to override the init method as well in order for the objectiveList array to be constructed. Basically, the code that is calling the init method is in here:
+(GameManager*)sharedGameManager {
#synchronized([GameManager class])
{
if(!sharedGameManager) {
sharedGameManager = [loadData(#"GameManager") retain];
if (!sharedGameManager) {
[[self alloc] init]; // GOES INTO INIT METHOD, NOT INITWITHCODER!
}
}
return sharedGameManager;
}
return nil;
}
On a side note, that singleton implementation gave me a headache. Just saying. :)
There is (as far as I can see from the code you have provided) a logic flaw in your code. Consider what would happen if decoder did not contain an objectiveList key; the else clause would execute, but you never allocated objectiveList so the addObjectsFromArray: call will silently fail.
To test this theory, alter your code as show below, and rerun. If the assertion fires then the above theory is correct, if not you need to hunt a bit more!
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self != nil)
{
if ([decoder containsValueForKey:#"objectiveList"])
{
objectiveList = [decoder decodeObjectForKey:#"objectiveList"];
}
else
{
NSAssert(objectiveList, #"objectiveList must be non-nil to add objects.");
[objectiveList addObjectsFromArray[NSArrayarrayWithObjects:#"1",#"2",#"3",#"4",#"5", nil]];
}
}
return self;
}
By the way, objectiveList is never declared as an ivar... I am sort of assuming that objectiveList and objectiveDescriptions are meant to be the same.
The method in GameManager.m should look like this:
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (self != nil) {
if ([decoder containsValueForKey:#"objectiveList"]) {
objectiveList = [[decoder decodeObjectForKey:#"objectiveList"] retain];
} else {
objectiveList = [[NSMutableArray alloc] initWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
}
}
You have two cases: either objectiveList is present, in which case you have previously saved some data, or it is not present and you need to create the default data (1, 2, 3, 4, 5). In the code above, I have changed the first case to retain the array returned by decodeObjectForKey, since Apple's docs state that this method returns an autorelease object. You need to retain it here to prevent the memory from being reused for some other objects that are created later in your app. By not retaining objectiveList, when accessing it later you were probably accessing garbage results (i.e. random memory) rather than what you had just decoded.
On a similar note, in the second case where objectiveList was not already present - i.e. for a new install of the app where there is no saved data present - you are not allocating objectiveList before trying to add objects to it. I have changed this line to actually alloc the object (and therefore the memory required), and then init with the default values you want. Since you were previously trying to add items to an array that had not been created, you would again get garbage data when trying to access the values from it. Note that I assume you are using an NSMutableArray here, but you might also be using an NSMutableSet.
I have an NSMutableArray object (retained, synthesized as all) that is initiated just fine and I can easily add objects to it using the addObject: method. But if I want to replace an object at a certain index with a new one in that NSMutableArray, it doesn't work.
For example:
ClassA.h:
#interface ClassA : NSObject {
NSMutableArray *list;
}
#property (nonatomic, copy, readwrite) NSMutableArray *list;
#end
ClassA.m:
#import "ClassA.h"
#implementation ClassA
#synthesize list;
- (id)init
{
[super init];
NSMutableArray *localList = [[NSMutableArray alloc] init];
self.list = localList;
[localList release];
//Add initial data
[list addObject:#"Hello "];
[list addObject:#"World"];
}
// Custom set accessor to ensure the new list is mutable
- (void)setList:(NSMutableArray *)newList
{
if (list != newList)
{
[list release];
list = [newList mutableCopy];
}
}
-(void)updateTitle:(NSString *)newTitle:(NSString *)theIndex
{
int i = [theIndex intValue]-1;
[self.list replaceObjectAtIndex:i withObject:newTitle];
NSLog((NSString *)[self.list objectAtIndex:i]); // gives the correct output
}
However, the change remains true only inside the method. from any other method, the
NSLog((NSString *)[self.list objectAtIndex:i]);
gives the same old value.
How can I actually get the old object replaced with the new one at a specific index so that the change can be noticed from within any other method as well.
I even modified the method like this, but the result is the same:
-(void)updateTitle:(NSString *)newTitle:(NSString *)theIndex
{
int i = [theIndex intValue]-1;
NSMutableArray *localList = [[NSMutableArray alloc] init];
localList = [localList mutableCopy];
for(int j = 0; j < [list count]; j++)
{
if(j == i)
{
[localList addObject:newTitle];
NSLog(#"j == 1");
NSLog([NSString stringWithFormat:#"%d", j]);
}
else
{
[localList addObject:(NSString *)[self.list objectAtIndex:j]];
}
}
[self.list release];
//self.list = [localList mutableCopy];
[self setList:localList];
[localList release];
}
Please help out guys :)
This does the trick:
[myMutableArray replaceObjectAtIndex:index withObject:newObject];
OK, there are a few bits of confusion here.
You don't need to take a mutableCopy of a newly created NSMutableArray to make it mutable. It's already mutable -- the clue is in the name. You only need to do that in the setter if you want the property to have copy semantics (which you've set, and may have good reason for, of course). But you certainly wouldn't need to do it as shown in your updated updateTitle code, and doing so leaks localList.
Also, you're mixing together property access via self.list and direct use of list in the same method. This is not invalid, but it's bad practice, because it means whatever other stuff the accessor methods do is being randomly bypassed. It's common for properties like this to do everything through self except in the accessors themselves, or in dealloc, and possibly in init (opinions seem to differ on this), where you would access the ivar directly.
Also, never call [self.list release] -- the property accessor doesn't give its caller ownership. Doing this will end in tears, mark my words.
None of this answers the real question, which is why is your change disappearing. The original updateTitle code does not explain this as far as I can see -- it should work. So I suspect that somewhere else you are calling self.list = theOriginalList and hence undoing your change.
Update:
Just for the sake of argument, I'm going to post what I think the code you posted is probably meant to look like. I've preserved your use of a string to pass the index to updateTitle, but I'd like to point out that doing it this way is wrong. It's a number, you should pass it as such. Even if the number comes from a text field or something, that's the caller's concern; the class interface should specify a number. Similarly the apparent change from 1-based to 0-based indexing. Please do not do this sort of thing implicitly, it is a recipe for weeping and gnashing of teeth.
ClassA.h:
#import <Cocoa/Cocoa.h>
#interface ClassA : NSObject
{
NSMutableArray* list;
}
- (void) setList:(NSMutableArray*)newList;
- (void) updateTitle:(NSString*)newTitle forIndex:(NSString*)theIndex;
#property (nonatomic, copy, readwrite) NSMutableArray* list;
#end
ClassA.m:
#import "ClassA.h"
#implementation ClassA
#synthesize list;
- (id) init
{
if ( self = [super init] )
{
list = [[NSMutableArray alloc] init];
[list addObject:#"Hello "];
[list addObject:#"World"];
}
return self;
}
- (void) setList:(NSMutableArray*) newList
{
if ( list != newList )
{
[list release];
list = [newList mutableCopy];
}
}
- (void) updateTitle:(NSString*)newTitle forIndex:(NSString*)theIndex
{
int i = [theIndex intValue] - 1;
[self.list replaceObjectAtIndex:i withObject:newTitle];
}
- (void) dealloc
{
[list release];
[super dealloc];
}
#end
This cleans up various issues, but note that updateTitle is mostly the same. If you drop all this in and the change still doesn't survive, you are definitely resetting list somewhere.
A more straight answer would be:
self.list[i] = newTitle;
This just works like
[self.list replaceObjectAtIndex:i withObject:newTitle];
Look at this line:
#property (nonatomic, copy, readwrite) NSMutableArray *list;
The copy means that whenever you access self.list, you don't get the "_list" instance variable of your object, but a copy of that list. If you write [self.list replaceObjectAtIndex... ] you replace an object in that copy of your list; the original _list is unchanged. Just use
#property (nonatomic, strong, readwrite) NSMutableArray *list;
And to avoid confusion, remove the "list" instance variable and the #synthesize statement, then use _list to access the instance variable.
For Swift you could try:
//if you have indexPath
self.readArray.removeAtIndex((indexPath?.row)!)
self.readArray.insert(tempDict, atIndex: (indexPath?.row)!)
//tempDict is NSDictionary object.
Finally Got Some Perfect Code,
let DuplicateArray: NSArray = array
let DuplicateMutableArray: NSMutableArray = []
DuplicateMutableArray.addObjectsFromArray(DuplicateArray as [AnyObject])
var dic = (DuplicateMutableArray[0] as! [NSObject : AnyObject])
dic["is_married"] = "false"
DuplicateMutableArray[self.SelectedIndexPath] = dic
array = []
array = (DuplicateMutableArray.copy() as? NSArray)!
//Output Will Be Like
array = [
{
"name": "Kavin",
"Age": 25,
"is_married": "false"
},
{
"name": "Kumar",
"Age": 25,
"is_married": "false"
}
]