Accessing Arrays throughout classes xcode - iphone

In my xcode project, whenever I try using:
#import "Class1.h"
NSMutableArray *array;
#implementation Class2
Class1 *class = [Class1 new];
array = class.array;
Assuming there is something called array in Class1.
Xcode builds it like there are no errors. However, when I run it, the screen flashes what is on class1 before crashing and giving me an error.
I fixed some other code. Now the error is:
[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
Sorry, I am new to Obj-C.

Designing your code. Design Pattern. These should be decided first, and thereafter coding is simpler.
As I can see you are creating a global array!!! Which is not good. If you want a shared array use SingletonClass/SharedClass.
Or you should put NSMutableArray *array; in .h file and alloc+init it to access it.
array = [class array];
This line is not clear, [class array] will return the array of Class1, so you must have NSArray in your Class2 where you are assiging Class1's array.
If Class2 has array as property use self.array=[class array];

If you want your array to be a property of Class1, you need to do something like this in your Class1.h file:
#interface Class1
#property (nonatomic, strong) NSMutableArray *array;
#end
Then you can access the array like in the code you posted.

Related

iOS error on array initialisation

I'm trying to initialise an array of Photos, and am doing so like this:
NSMutableArray *photoList = [[NSMutableArray alloc] init];
self.photos = photoList;
But when this line of code runs, I get this error:
'NSInvalidArgumentException', reason: '-[Project setPhotos:]: unrecognized selector sent to instance 0xee8e310'
I've spent about three hours trying to find a fix but couldn't, can anybody tell me what to do?
It seems to me that you haven't created a property photos and if you have then it would also seem that this property is not #synthesize'd in your implementation, maybe you are using #dynamic, in which case it is up to you to create a - (void)setPhotos:(NSMutableArray*)photos; method
self does not have a property called photos
You need to add #property (nonatomic, strong) NSArray *photos; in your .h file, before the #end
and in the .m file, #synthesize photo;
This line of code:
self.photos = photoList;
gets turned into this line
[self setPhotos:photoList];
by the compiler - the dot notation is what is called "syntatic sugar" as is just makes it easier to type, it doesn't really shorten the code.
If you have created your own getters and setters (ie)
- (NSMutableArray *)photos;
- (void)setPhotos:(NSMutableArray *)myPhotos
Then you can use that sugar even though you don't have a property called "photos" - although this is considered a misuse of the feature (I show it for comparison purposes).
When you create a property named photos:
#property (nonatomic, strong) NSMutableArray *photos;
the compiler will generate an ivar for you using the same name, but not create the getters and setters. The line:
#synthesize photos;
asks the compiler to do a getter (in all cases) and a setter (if the property is read write). If you do not provide a #synthesize statement, the compiler normally complains, so people should be observing these warnings.
You can see in the error that you have no setPhotos, thus your problem can be fixed quite easily.
Seems like you haven't written a setter method for photos.
in your .h
#property (strong, nonatomic) NSArray * photos;
in your .m (if not using xcode 4.4)
#synthesize photos;
or you could just try writing it like this
photos = [NSArray arrayWithArray:photoList];
For reference if you use [self setMyArray:array] or self.array = myArray
Then you are using the setter method, which is something you probably want to do. If you just point array = myArray, you would be pointing to myArray and if it were released your pointer would point in to the abyss. It's good to not to do that, not using the setter means you are accessing the variable photos directly and this may not be what you want.
Whoops, I'd used #dynamic photos instead of #synthesize photos

Regarding NSPredicate and NSMutableArray deep copy

I am trying to copy NSMutableArray which is based of my Registration NSMutableArray Class and trying to filter a boolean. The concern is, since the nsmutablearray is from the class, each time I try to alloc and initwitharray:[self person] man]; where man is a nsmutablearray it doesn't allow me to do it. Is this functionality only localized or can be globally utilized as well? Or am I missing something here?
Thanks.
You have to make sure that "man" is declared as a property of "[self person]". i.e. in the header of the class that [self person] is an instance of,
#property (nonatomic, retain) NSMutableArray *man;
and in the implementation:
#synthesize man;

Accessing Class Data Members in ViewController.m (xCode / Objective C)

I have a class myClass and would like to access its properties, a NSArray *currentOptions (specifically to get the size of currentOptions and access the NSStrings which I've put in it.)
I have a method called generate options which assigns an filled array to *currentOptions. Generate options is called before I try to access *currentOptions. An instance of myClass has also been added to the ViewController via the App delegate. However when buttonOnePressed is called, I keep getting this error:
[myClass currentOptions]: unrecognized selector sent to instance 0x9b10490
Here is the parts of my code:
//TClass.h
#interface TClass : NSObject {
NSArray *currentOptions;
}
#property (nonatomic, retain) NSArray *currentOptions;
#end
//viewController
- (IBAction) buttonOnePressed:(id)sender {
NSLog(#"button1 pressed");
NSLog(#"int: %d",[myClass.currentOptions count]);
//myClass here is the instance of TClass
}
One thing that sometimes causes that error is failing to properly retain myClass. (Aside: "myClass" is a really bad name for a pointer because the thing being pointed to is almost certainly not a class but an object, i.e. an instance of a class.) If you don't retain the object that myClass points to, it will be deallocated. Sometimes, a different object happens to be created at that some location, and you end up sending a message meant for the original object to the new one, which is a different type and doesn't understand the message.
To all who have been following, the problem has been resolved by making the following changes:
1) Synthesized current options TClass.m
#implementation TClass
#synthesize currentOptions;
#end
2) I made currentOptions a NSMutableArray instead of a NSArray. This is because I need to reassign values to current options. Somehow it crashes with NSArray and everything goes smoothly with NSMutable array like such
#implementation TutorialClass
if ([currentOptions count] > 0) {
[currentOptions removeAllObjects];
}
[currentOptions addObject:[options objectAtIndex:0]];
[currentOptions addObject:[options objectAtIndex:1]];
[currentOptions addObject:[options objectAtIndex:2]];
[currentOptions addObject:[options objectAtIndex:3]];
3) And of course, I'll also have to do the following in the init method of TClass.m
currentOptions = [[NSMutableArray alloc] init];
Now its time to get some food. Thanks Caleb :D

How do I populate an NSMutableArray in one class with another object?

I know this is a simple answer, but I can't seem to find the solution. I created an object in its own class and I am trying to populate it with data from another class. For simple data types like NSString, I have no problem, but when trying make an NSMutableArray equal to another NSMutableArray or when I try to populate a NSMutableArray with another objects (like strings), I keep getting exception errors...
Here is the object I am trying to populate:
#import <Foundation/Foundation.h>
#interface RSSFeedList : NSObject {
NSString *subject;
NSMutableArray *rssfeedDetail;
}
#property (nonatomic, retain) NSString *subject;
#property (nonatomic, retain) NSMutableArray *rssfeedDetail;
#end
This is how I was able to populate the NSString 'subject' in another class:
rssFeedList.subject = #"test";
However, if I follow similar convention within that same class with respect to an Array, it throws an exception:
rssFeedList.rssfeedDetail = rssItemDetailArray;
Where rssItemDetailArray is a NSMutableArray that I have built in the same class.
I have also tried to add items (i tried strings for testing) to the NSMutableArray directly like so to no avail:
[rssFeedList.rssfeedDetail addObject:#"test"];
Any ideas?? Thanks in advance!!
I'm almost certain that you've forgotten to synthesize rssfeedDetail.

NSMutableArrays

I have an NSMutableArray as a member variable for a class.
In the .h file:
#interface bleh {
NSMutableArray *list;
}
#property (readonly, assign) NSMutableArray *list;
#end
In the .m file:
#implementation bleh
#synthesize list;
-(void)init;
{
list = [NSMutableArray arrayWithCapacity:30];
}
#end
Now, I'm not really an objective-C programmer, so maybe I'm missing some of the nuances, but when I do the following:
NSMutableString *listItem = [NSMutableString stringWithString:#"Foobar"];
[list addObject:listItem];
I'm getting strange behavior. Namely, I'm using this to keep a list of files that I eventually want to attach to an email and then open the picker. I'm getting a SIGABRT, and upon debugging, I find out that whenever I operate on list, I'm getting nothing. addObject messages don't increase the size of the NSMutableArray at all.
Am I missing something? Can someone show me a full implementation of setting up an NSMutableArray to be manipulated within a class in Objective C?
Thanks.
PS - Assume that I'm smart enough to put the manipulations of the NSMutableArray inside of a member function for the class containing the member variable.
in the latest release of the SDK arrayWithCapacity is bad practice.
but in your code you creating a array that no one is owner , clam your array properly.
don't forget initialize your array
NSMutableArray *array = [[NSMutableArray alloc] init];
fix the (readonly,assign),
How are you actually creating your array? Is it possible that it's being autoreleased and going away? Remember, if you create it with a convenience method (like array or something) you need to retain it.
You're creating the array with arrayWithCapacity:, which returns an array you don't own, and you're never claiming ownership over it. Use a property accessor to retain the array:
self.list = [NSMutableArray arrayWithCapacity:30];
I would recommend reading the Cocoa memory management docs. Once you know the rules in there, it will be clear what to do in this sort of situation. They're not very hard, but they are very necessary if you're going to be programming Cocoa.
Your list variable has been auto-released and de-allocated, therefore your program crashes when you try to access it.
There are two ways to create objects in Cocoa:
NSMutableArray* array1 = [[NSMutableArray alloc] initWithCapacity:10];
NSMutableArray* array2 = [NSMutableArray arrayWithCapacity:10];
array1 was created using alloc+init, therefore you own it. It will stick around until you release it.
array2 was not created using alloc+init, therefore you do not own it. You're not responsible for releasing it, but it will go away on its own. You must retain array2 if you want it to stick around.
Your list property declaration is keeping you from properly retaining the NSMutableArray. By calling arrayWithCapacity you're effectively putting the array in an autorelease pool, which means it could be deallocated at any time if no object interested in keeping it around. While you are, the way you have things declared doesn't reflect that:
#property (readonly, assign) NSMutableArray *list;
The above declaration simply sets this pointer to be a copy of another pointer - it does no memory management for you. Instead it should read:
#property (readonly, retain) NSMutableArray *list;
... and you should assign the list like so:
self.list = [NSMutableArray arrayWithCapacity:64];
Because you specify the retain attribute for the property, whenever it is assigned a new value the retain message will be sent to that new value, communicating to the memory manager that you don't want this object deallocated. In order to bring this full circle, you'll need to release the object when you containing class is deallocated:
- (void)dealloc
{
[list release];
[super dealloc];
}
Are you initializing your list properly? Ie do you have something like the following in your code?
list = [[NSMutableArray alloc] init];
Problem ehre (assuming you initing your array properly) could be that #"Foobar" assings an NSString not an NSMutableString so its failing because if distinct types you should do
NSMutableString *listItem = [NSMutableString stringWithString:#"Foobar"];
[list addObject:listItem];
or
NSString *listItem =#"FooBar";
[list addObject:listItem];
It doesn't look as though you've actually initialized the NSMutableArray.
In the init event of the object, just say
[self setList:[[NSMutableArray alloc] initWithCapacity:10]]];
(I would just say init, but I don't remember if that works. It doesn't matter what capacity you start with)
Before actually allocating the array, the variable "list" will have a value of nil.