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.
}
Related
I have this code in objc that creates an array with some values from realm
get.m
-(void) menuTest {
RLMResults<activity *> *test = [activity allObjects];
NSMutableArray *tmpArray = [[NSMutableArray alloc] init];
for(activity *n in test){
[tmpArray addObject:n];
}
}
And I want to have access to that array in my swift class to populate some dropdown menu. As of now I am calling it like this but it tells me it doesn't conform to protocol.
let get = get()
for n in get.menuTest(){
array.append(n)
}
How can I make a call to the objc array?
The menuTest function returns void, if you want to access the array you have to change it in this way:
- (NSMutableArray*)menuItems {
RLMResults<activity *> *test = [activity allObjects];
NSMutableArray *tmpArray = [[NSMutableArray alloc] init];
for(activity *n in test){
[tmpArray addObject:n];
}
return tmpArray
}
MY CODE
.h
#interface fileHandler : NSObject
#property NSMutableArray *arrCategoryList;
#property NSMutableDictionary *dicCategoryList;
#property NSMutableDictionary *dicAllSubCategoryList;
#property NSMutableDictionary *dicProductList;
+(fileHandler *)getDataHandler;
-(void)categoryStorage:(NSMutableArray *)arrCategory :(NSMutableDictionary *)dicCategory :(NSMutableDictionary *)dicSubCategory;
.m
static fileHandler *internalInstance=Nil;
static dispatch_once_t internalOnceToken=0;
#implementation fileHandler
-(id)init
{
self=[super init];
[self allocateMemory];
return self;
}
+(fileHandler *)getDataHandler
{
dispatch_once(&internalOnceToken,^{
internalInstance = [[fileHandler alloc] init];
if(internalInstance) {
NSLog(#"Internal instance created: %#", internalInstance);
}
});
if(internalOnceToken == -1) {
NSLog(#"Internal instance exists: %#", internalInstance);
}
return internalInstance;
}
-(void)allocateMemory
{ NSLog(#"incoming");
self.arrCategoryList=[[NSMutableArray alloc]init];
self.dicCategoryList=[[NSMutableDictionary alloc]init];
self.dicAllSubCategoryList=[[NSMutableDictionary alloc]init];
self.dicProductList=[[NSMutableDictionary alloc]init];
}
-(void)categoryStorage:(NSMutableArray *)arrCategory :(NSMutableDictionary *)dicCategory :(NSMutableDictionary *)dicSubCategory
{
// arrCategory =[[NSMutableArray alloc]init];
self.arrCategoryList=arrCategory;
// [self.arrCategoryList addObject:arrCategory];
// NSLog(#"inside data handler file==%#",self.arrCategoryList);
// dicCategory=[[NSMutableDictionary alloc]init];
self.dicCategoryList=dicCategory;
// dicSubCategory=[[NSMutableDictionary alloc]init];
self.dicAllSubCategoryList=dicSubCategory;
}
Here i have created the static thread and then i am trying to store all the values in to mentioned array and dictionary in other class ,once i have stored the values here then i have to access those data to any where in my app.
Is it Possible?
Is it Right Way?
Another classFile
.m
Like this i am trying to store the values in NSobject Class Array.
for(NSDictionary *DicHoleCategories in ArrCategory)
{
NSMutableDictionary *DicAllValues=[[NSMutableDictionary alloc]init];
[DicAllValues setObject:[[DicHoleCategories objectForKey:#"name"] length] !=0?[DicHoleCategories objectForKey:#"name"] :#"" forKey:#"name"];
StrName=[DicHoleCategories objectForKey:#"image"];
[DicAllValues setObject:[DicHoleCategories objectForKey:#"subcategory"] forKey:#"subcategory"];
if(StrName!=nil)
{
subimages=[NSString stringWithFormat:LocalImage"%#",StrName];
[DicAllValues setObject:subimages forKey:#"image"];
[arrImages addObject:[DicAllValues objectForKey:#"image"]];
}
[ArrName addObject:DicAllValues];
[arrSubCategory addObject:[DicAllValues objectForKey:#"subcategory"]];
[dicSubCategory setObject:[DicAllValues objectForKey:#"subcategory"] forKey:#"subcategory"];
[dicAllValues setObject:dicAllValues forKey:#"hole"];
}
[file categoryStorage:ArrCategory :dicAllValues :dicSubCategory];
OUTPUT:
Collection <__NSArrayM: 0x7f8c33c7b220> was mutated while being enumerated.'
Have a question about blocks in objective-c.
For example I have a list of actions.
I'm initializing an array of blocks:
self.actions = #[
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; }
];
And calling them when some row is pressed:
- (void)pressedRowAtIndex:(NSInteger)index {
if (index < actions.count) {
void (^action)() = [actions objectAtIndex:index];
if (action != nil) {
action();
}
}
}
And all works fine without problem. But when I init my actions array by using initWithObjects method:
self.actions = [NSArray alloc] initWithObjects:
^() { [self showObject:self.object_1]; },
^() { [self showObject:self.object_2]; },
^() { [self showObject:self.object_3]; },
nil
];
Than I get crash trying to get action by index by using objectAtIndex method of NSArray class.
I understand the difference between this inits. First one don't increase reference count like first do. But can someone explain why it crash?
Edit:
All that I've found. Maybe I'm nub and somewhere else is another useful information.
There is no crash info in terminal:
Code for Onik IV:
Small example:
#interface ViewController () {
NSArray *actions;
}
#property (nonatomic, strong) NSString *object1;
#property (nonatomic, strong) NSString *object2;
#property (nonatomic, strong) NSString *object3;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
actions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; },
nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.object1 = #"object 1";
self.object2 = #"object 2";
self.object3 = #"object 3";
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [actions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(#"Show: %#",object);
}
#end
Try something like this.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
(^someBlock)(void) = ^void(void){
self.object1;
};
actions = [[NSArray alloc] initWithObjects:
[someBlock copy],
[someOtherBlock copy],
[anotherBlock copy],
nil];
}
Blocks are allocated on the stack and are therefor removed when the frame is removed from the stack leading to sail pointers for all pointers pointing to that block. When you allocate a object with the literal "#" sign the object is allocated in a pool so all literals that are the "same" point to the same instance and are never deallocated.
NSString *a = #"A";
NSString *b = #"A";
points to the same instance of a string, while:
NSString *a = [NSString stringWithFormat:#"A"];
NSString *b = [NSString stringWithFormat:#"A"];
are two different objects.
So it works when you are creating a literal array but when you add the blocks dynamically they will be removed when its time to use them therefor the BAD_ACCESS. Solution is to send "copy" message to the block that will copy it to the heap and the block will not be released.
It´s the same, you must have another kind of problem (sintax?).
Try this:
#interface ViewController ()
#property (nonatomic, strong) NSString *object1;
#property (nonatomic, strong) NSString *object2;
#property (nonatomic, strong) NSString *object3;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.object1 = #"object 1";
self.object2 = #"object 2";
self.object3 = #"object 3";
NSArray *actions = #[^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() {[self showObject:self.object3]; }
];
NSArray *secondActions = [[NSArray alloc] initWithObjects:
^() { [self showObject:self.object1];},
^() { [self showObject:self.object2]; },
^() { [self showObject:self.object3];},
nil
];
void(^firsSimpleBlock)(void) = [actions lastObject];
firsSimpleBlock();
void(^simpleBlock)(void) = [secondActions firstObject];
simpleBlock();
}
-(void)showObject:(NSString *)object
{
NSLog(#"Show: %#",object);
}
#end
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];
}
In creating a login screen with static logins I'm trying to store them privately in the following class implementation. When a button creates IONServer objects I initialize it with the function -(void)login:(NSString *)username password:(NSString *)pw and pass it two UITextField.text strings.
If you notice in the init I am testing stuff with NSLog but at every breakpoint it seems like the storedLogins NSMutable array is nil.
IONServer.m
#import "IONServer.h"
#import "IONLoginResult.h"
#interface IONServer ()
#property (nonatomic) NSMutableArray *storedLogins;
#end
#implementation IONServer
-(void)createStoredLogins
{
NSArray *firstUser = #[#"user1",#"pass1"];
NSArray *secondUser = #[#"user2",#"pass2"];
[self.storedLogins addObject:firstUser];
[self.storedLogins addObject:secondUser];
}
-(instancetype)init {
self = [super init];
if (self) {
[self createStoredLogins];
NSLog(#"Stored logins: %#", _storedLogins);
NSLog(#"Stored user: %#", _storedLogins[0][0]);
}
return self;
}
-(void)login:(NSString *)username password:(NSString *)pw
{
NSArray *logins = [[NSArray alloc]initWithArray:_storedLogins];
for (int i = 0; i < [logins count]; i++) {
if (username == logins[i][0] && pw == logins[i][1]) {
IONLoginResult *result = [[IONLoginResult alloc] initWithResult:YES errorMessage:#"Success!"];
self.result = result;
break;
} else {
IONLoginResult *result = [[IONLoginResult alloc] initWithResult:NO errorMessage:#"Error!"];
self.result = result;
}
}
}
-(void)logout
{
}
#end
You need to initialize the array:
-(instancetype)init {
self = [super init];
if (self) {
_storedLogins = [[NSMutableArray alloc] init];
[self createStoredLogins];
NSLog(#"Stored logins: %#", _storedLogins);
NSLog(#"Stored user: %#", _storedLogins[0][0]);
}
return self;
}