Making NSArray a NSMutableArray inside an if condition - ios

I have a array inside my init method and then I wish to make a mutable array inside if condition when it's actually needed. Is it possible?
Presently am doing:
- (id)init
{
self = [super init];
if (self)
{
// [MyClass someMethod] in the below statement returns an array.
NSMutableArray *someArray = [NSMutableArray arrayWithArray:[MyClass someMethod]];
if (this condition is true)
{
[someArray addObject:#"XYZ"];
}
// Print someArray here.
}
}
What I am trying to do it:
- (id)init
{
self = [super init];
if (self)
{
// [MyClass someMethod] in the below statement returns an array.
NSArray *someArray = #[[MyClass someMethod]];
if (this condition is true)
{
// Make some array mutable here and then add an object to it.
[someArray mutableCopy];
[someArray addObject:#"XYZ"];
}
// Print someArray here.
}
}
Am I doing it right? Or is what I am thinking possible? Can I make the same array mutable whenever needed as in my case I need it to be mutable only if my condition in if is true.

You should change code in if condition:
if (this condition is true)
{
// Make some array mutable here and then add an object to it.
NSMutableArray *mutableArray = [someArray mutableCopy];
[mutableArray addObject:#"XYZ"];
someArray = mutableArray.copy;
}

How about this?
{
NSArray *array;
if(condition)
{
NSMutableArray *mutaArray = [NSMutableArray arrayWithArray:[MyClass someMethod]];
[mutaArray addObject:#"XYZ"];
array=mutaArray;
}
else
array=[MyClass someMethod];
}

Related

How to work with one array in two methods

How can i insert value in array in one method and work with this full of value array in other method.
-(void)firstMethod {
NSMutableArray *array = [[NSMutableArray alloc] init];
../// add some value in array.
}
-(void)secondMethod {
..// here i want to work with array which consist of value from first method.
}
You can create one instance of NSMutableArray and use that in the both method.
#interface ViewController () {
NSMutableArray *array;
}
#end
Now access this array in both methods
-(void)firstMethod {
array = [[NSMutableArray alloc] init];
[array addObject:#"Hello"];
}
-(void)secondMethod {
if (array) {
[array addObject:#"World"];//Add object that you want
}
else {
array = [[NSMutableArray alloc] init];
[array addObject:#"World"];
}
}
You can declare a NSMutableArray property
#interface ViewController ()
#property(nonatomic,strong)NSMutableArray *array;
#end
create instance in init method
- (instancetype)init{
if(self == [super init]) {
_array = [NSMutableArray array];
}
return self;
}
-(void)firstMethod {
[self.array addObject:#"obj1"];
}
-(void)secondMethod {
[self.array addObject:#"obj2"];
}
YOU CAN USE BELOW CODE:
#property (nonatomic, strong) dispatch_queue_t concurrentQueue;
_concurrentQueue= dispatch_queue_create("any String", DISPATCH_QUEUE_CONCURRENT);
- (NSArray *)secondMethod
{
__block NSArray *array;
dispatch_sync(self.concurrentQueue, ^{
array= [NSArray arrayWithArray:array];
});
return array;
}
- (void)firstMethod:(NSString *)str
{
if (str) {
dispatch_barrier_async(self.concurrentQueue, ^{
[array addObject:str];
dispatch_async(dispatch_get_main_queue(), ^{
//Do some asynchronous work
});
});
}
}
Other answers suggest you to declare array as property. But usually it's more clear to just pass needed data as arguments to another method:
-(void)firstMethod {
NSMutableArray *array = [[NSMutableArray alloc] init];
../// add some value in array.
[self secondMethod:array];
}
-(void)secondMethod:(NSArray *)array {
..// here i want to work with array which consist of value from first method.
}

addObject for NSMutableArray not working

#property (strong, nonatomic)NSMutableArray *billsArray;
- (void)viewDidLoad {
[super viewDidLoad];
self.billsUserDefault = [NSUserDefaults standardUserDefaults];
self.billsArray = [[NSMutableArray alloc] init];
self.billsArray = [self getBillsArray];
}
- (NSMutableArray *)getBillsArray {
NSMutableArray *billsArr = [self.billsUserDefault objectForKey:#"billArray"];
return billsArr;
}
- (void)AddOneBill:(Bill *)bill {
// add bill to array
[self.billsArray addObject:bill];
// store the new bill
[self.billsUserDefault setObject:self.billsArray forKey:#"billArray"];
[self.billsUserDefault synchronize];
// reload the table view
[self.billTableView reloadData];
}
The addObject method in addOneBill: method does not work.
I have googled the same problem, others also met this problem. The answers suggested to add [[NSMutableArray alloc] init] for mutable array. I did but not works.
In your getBillsArray method, add mutableCopy call to get mutable array for objectForKey. Because objects got from NSUserDefaults are not mutable. Modified code would look like this:
- (NSMutableArray *)getBillsArray {
NSMutableArray *billsArr = [[self.billsUserDefault objectForKey:#"billArray"] mutableCopy];
return billsArr;
}
EDIT:
You are adding custom objects in array and trying to save in NSUserDefaults which is not possible. You need to convert your object into NSDictionary object in which each key value pair will represent one variable of that object. You will have to recursively do this conversion step if your custom object also contain custom objects.
- (void)viewDidLoad {
[super viewDidLoad];
self.billsUserDefault = [NSUserDefaults standardUserDefaults];
self.billsArray = [[NSMutableArray alloc] init];
self.billsArray = [self getBillsArray];
}
In viewDidLoad you call getBillsArray. But what value in userDefauls for key - billArray you what to get at viewController start?
You set array for this key in addOneBill method.
So in viewDidLoad you creates mutableArray:
self.billsArray = [[NSMutableArray alloc] init];
and then set it to nil here:
self.billsArray = [self getBillsArray];
Try
NSMutableArray *billsArr = [[self.billsUserDefault objectForKey:#"billArray"] mutableCopy]; in getBillsArray
NSUserDefaults objects are not not mutable. You have to make them mutable.
try following code.
NSMutableArray *billsArr = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"billArray"]];
Another solution : For the explication why it does not work, see Salman's answer (Returned values from NSUserDefaults are not mutable)
- (void)viewDidLoad {
[super viewDidLoad];
self.billsUserDefault = [NSUserDefaults standardUserDefaults];
self.billsArray = [[NSMutableArray alloc] init];
[self.billsArray addObjectsFromArray: [self getBillsArray]];
}
- (NSArray *)getBillsArray {
NSArray *billsArr = [self.billsUserDefault objectForKey:#"billArray"];
return billsArr;
}
In order to save your 'Bill' objects into NSUserDefaults, if it's derived from NSObject, you can use NSKeyedArchiver & NSKeyedUnarchvier:
//encode
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:your_bill_array];
//then save to NSUserDefaults
//decode:
id result = [NSKeyedUnarchiver unarchiveObjectWithData:data_returned_from_NSUSerDefaults];

How to access an instance variable by an NSString generated at run-time (reflection)

I've got the following little code conundrum..
- (void) transmitArray {
NSString* arrayName = #"array1";
NSArray* array1 = [NSArray arrayWithObject:#"This is Array 1"];
NSArray* array2 = [NSArray arrayWithObject:#"This is Array 2"];
NSMutableArray* targetArray = [NSMutableArray arrayWithCapacity:1];
}
Is there a way to use the string "array1" to access the NSArray 'array1' so I can copy it into the target array.. And therefore, if the string read "array2", I'd be able to access the second array?
I read about using NSSelectorFromString to create a selector, and that this technique was called 'introspection', but other than that I'm stumped..
Hope someone can help!
Not really. If it were a instance variable of the class (generally known as a property) then you could use introspection to inspect the object and get/set the needed variables. You can can use the KVO methods
setValue:(id) ForKeyPath:(NSString *)
and
valueForKeyPath:(NSString *)
to access them
However you can't do that with local variables declared inside of an instance method (directly). I would suggest populating a dictionary with your arrays and then using it as a lookup table
NSMutableDictionary *arrays = [[NSMutableDictionary alloc] init];
NSArray *array1 = #[#"This is Array 1"];
[arrays setObject:array1 forKey:#"array1"];
NSArray *array2 = #[#"This is Array 2"];
[arrays setObject:array1 forKey:#"array2"];
//grab a copy of array1
NSArray *targetArray = [arrays[#"array1"] copy];
If you have array1 declared as a property you can do it like this:
#import "ViewController.h"
#interface ViewController ()
#property NSArray *array1;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.array1 = [NSArray arrayWithObjects:#"Hello", #"world!", nil];
NSArray *array2 = [self valueForKeyPath:#"array1"];
NSLog(#"%#", array2);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Compare two arrays and set an if else

I need to compare two arrays (A & B), than for the elements of A that belong also to B I need to set an if statement. Just to explain me better:
if (elementOfArrayA belong AlsoToarrayB) {
//do something
}else{
//do something else
}
Someone could help me?
Thanks
NSArray has an instance method called containsObject: exactly for this.
For further clarification, check this out.
Use following code to compare two array :
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",nil];
for(int i = 0;i<[array1 count];i++)
{
for(int j= 0;j<[array2 count];j++)
{
if([[array1 objectAtIndex:i] isEqualToString:[array2 objectAtIndex:j]])
{
} else {
}
}
}
Comparing two arrays:
if([arrayA isEqualToArray:arrayB]){
//the two arrays A and B are equals
}
The code above will test ALL elements of both arrays to check if they fulfill the isEqual test, so no need to for loop the array.
If you want to check wether an element of arrayA is contained in arrayB, use the following method:
id firstCommonObject = [arrayA firstObjectCommonWithArray:arrayB];
if(firstCommonObject != nil){
//a common object between arrayA and arrayB has been found
}else{
//no common objects between both arrays
}
// Method 1 - Simplest method to solve above problem (Use NSArray's containsObject method)
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",#"e", nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",#"f", nil];
for(id i in array1){
if ([array2 containsObject:i]) {
// do something
}
else {
// do something else
}
}
// Method 2 - Another method (Use NSString's isEqualToString method)
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",#"e", nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",#"f", nil];
for(id i in array1){
for(id j in array2){
if ([i isEqualToString:j]) {
// do something
}
else {
//do something else
}
}
}
it may be help you...
-(void)methodFour
{
NSArray *arr1 = [[NSArray alloc]initWithObjects:#"a2223a",#"ab33b",#"a1acdf",#"ac23c45", nil];
NSArray *arr11 = [arr1 sortedArrayUsingSelector:#selector(localizedCompare:)];
NSLog(#"%#",arr11);
NSArray *arr2 = [[NSArray alloc]initWithObjects:#"ab33b",#"ac23c45",#"a1acdf",#"a2223a", nil];
NSArray *arr22= [arr2 sortedArrayUsingSelector:#selector(localizedCompare:)];
[self firstArray:arr11 secondArray:arr22];
}
-(void)firstArray:(NSArray *)array1 secondArray:(NSArray *)array2
{
if ([array1 isEqualToArray:array2])
{
NSLog(#"equal");
}
else
{
NSLog(#"Not equal");
}
}

iOS:Retrieve data from function input parameter

I want to know how to retrieve the values by giving input parameter to a function. I want to retrieve in this way here as below, but it doesn't retrieve it rather giving empty array value when printing. I can't use even ampersand like c in parameter.
NSMutableArray *firstArray = [[NSMutableArray alloc] init];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
MyClass *myClassObj = [[MyClass alloc] init];
[myClassObj getVals : firstArray : secondArray];
NSLog(#"firstArray: %#", firstArray); // empty
NSLog(#"secondArray: %#", secondArray); // empty
// function to retrieve
- (void) getVals :(NSMutableArray *) firstArray :(NSMutableArray *) secondArray
{
firstArray = [NSMutableArray arrayWithObjects:#"val1", #"val2", #"val3", #"val4", nil];
secondArray = [NSMutableArray arrayWithObjects:#"val11", #"val22", #"val33", #"val44", nil];
}
Try this:
- (void) getVals :(NSMutableArray *) firstArray :(NSMutableArray *) secondArray {
[firstArray addObjectsFromArray:#[ #"val1", #"val2", #"val3", #"val4" ]];
[secondArray addObjectsFromArray:#[ #"val11", #"val22", #"val33", #"val44" ]];
}
The code you have assigns a new array to the local parameter values instead of adding values to the passed in arrays.
Your other option could be:
NSMutableArray *firstArray = nil;
NSMutableArray *secondArray = nil;
MyClass *myClassObj = [[MyClass alloc] init];
[myClassObj getVals : &firstArray : &secondArray];
- (void) getVals :(NSMutableArray **) firstArray :(NSMutableArray **) secondArray {
*firstArray = [NSMutableArray arrayWithObjects:#"val1", #"val2", #"val3", #"val4", nil];
*secondArray = [NSMutableArray arrayWithObjects:#"val11", #"val22", #"val33", #"val44", nil];
}
You are overriding the object reference with new object. U should rather use
[firstArray addObject:#"val1"]

Resources