#property (nonatomic, retain) NSMutableArray *filteredListContent;
----
#synthesize filteredListContent;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSMutableArray *test = [[NSMutableArray alloc] init];
[test addObject:#"test string"];
[filteredListContent addObjectsFromArray:test];
NSLog(#"%#", test);
NSLog(#"Filtered Array is %#", filteredListContent);
[window makeKeyAndVisible];
}
My Log for test shows 'test string' but 'Filtered list array is (null)'
How do I set the array 'filteredListContent' with the array test...
What am I doing wrong? :-(
Are you creating and initializing filtersListContent anywhere? Your code looks right, that should work.
You should also make sure to release your test variable, you have a memory leak here.
You have to actually create filteredListContent, say with [[NSMutableArray alloc] init]. The error you are getting is that you are calling a method, -addObjectsFromArray:, on an object that is still nil: never created. As such, it just returns nil, and the list is never filtered.
filteredListContent is a pointer to a NSMutableArray, it does not have any memory assigned to it, as a result you cannot call methods on it. The compiler does not generate an error because you are passing a message to nil which is perfectly alright.
Thanx for that.
so I changed the line...
[filteredListContent addObjectsFromArray:test];
to read...
filteredListContent = [NSMutableArray arrayWithArray:test];
This done it. I think I understand it now, though I declared it, I never created it...
Thanx.
Related
I have an NSMutableArray I'm trying to reload after an async call. The first time it loads like this:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
After the user does some interaction, the same line will be reached to reload the NSMutableArray. This causes the crash
Header file has:
#interface...
NSMutableArray *sessionProcList;
... }
#property (nonatomic, retain) NSMutableArray *sessionProcList;
Say you do:
NSMutableArray *a = [NSMutableArray arrayWithObject: [[NSObject alloc] init]];
NSObject *o = [a objectAtIndex: 0];
[a removeAllObjects];
[o description]; // *BOOM*
The above will [generally -- sometimes not but only by coincidence] crash because o has been deallocated by the time the description method is invoked.
If you have a reference to an object in an array, but have not retained said reference, then said object may be deallocated out from under you when you empty the array.
(And nonatomic vs. atomic is irrelevant.)
If I had to guess, I would say that elements in that array are being referenced from somewhere else. Resetting the array causes the items using the references to crash.
I would check your application for other variables, properties, or UI elements using those variables that have not been release before resetting it.
Because arrayWithArray is a convenience method it gets initialised with an autorelease flag.
You haven't mentioned what the crash / error message is but I am guessing your NSMutableArray is getting released before your second iteraction with it starts.
Try and retain the array for however long you need it with:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
[sessionProcList retain];
And then release it when you're done with it:
[sessionProcList release];
I hope it helps.
Rog
So i have a uiviewcontroller. It has a property of an NSMutableArray with a nonatomic, retain property synthesized.
In the viewDidLoad I init it with the following, and also add a button to the nav bar.
test = [NSDictionary dictionaryWithObjectsAndKeys:
[[SearchField alloc] initWithName:#"Subject" :Text], kSubjectKey,
[[SearchField alloc] initWithName:#"Source publication" :Text], kSourceKey,
[[SearchField alloc] initWithName:#"Keyword" :Text], kKeywordKey,
[[SearchField alloc] initWithName:#"Author" :Text], kAuthorKey,
[[SearchField alloc] initWithName:#"Color" :Bool], kColorKey,
nil ];
NSLog([NSString stringWithFormat:#"lol %d", [test count]]);
The first log, when running through the debugger runs fine. However, I have tied the following code to the button:
-(void)search:(id)sender{
NSLog([NSString stringWithFormat:#"lol %d", [test count]]);
When this code executes the log line crashes with exc bad access. Nothing is happening to the NSDictionary between the viewDidLoad and the button press, so why is this happening? And more importantly, how do I fix it? :)
Cheers
Edit
I thought maybe it was my SearchField class was doing things, so i replaced them with simple strings, the problem still occurs.
You're directly accessing the member variable - you need to go through the accessor - ie:
self.test = [NSDictionary dictionaryWithObje ...
This will make sure your object retains the dictionary.
Make sure test is a class variable, by setting it up as a property of your view controller's header:
#property (nonatomic, retain) NSDictionary *test;
Release it in your view controller's -dealloc method:
[test release], test = nil;
Set its value as follows:
self.test = [NSDictionary dictionaryWithObjectsAndKeys:...];
Access its count property as follows:
NSLog(#"Count: %u", test.count);
Or:
NSLog(#"Count: %u", [test count]);
Note that -count returns an unsigned integer, so you should use %u to format its value.
The dictionary you're creating is autoreleased. You're using a convenience method (dictionaryWithObjectsAndKeys:) which returns a new autoreleased object.
The autoreleased object is being released (and deallocated) some time after its creation, which is why it's crashing later in the program.
You need to retain the returned dictionary, or create a new dictionary using the alloc/init method.
Either way, you need to remember to release the dictionary when you're done with it.
You should read up on the basic memory management rules and conventions for Objective-C.
I made my own class derived by NSObject, and here is my code:
-(void) parseRow:(NSDictionary*) dictionary {
NSArray* arName = [[dictionary valueForKey:displayname] componentsSeparatedByString:#"+"];
[self setDriverName:[arName objectAtIndex:0]];
[self setDriverSurname:[arName objectAtIndex:1]];
[arName release]; // this give problem!
}
and in my view:
driverStats = [[DriverStats alloc] init];
// driverStats is declared in the header:
DriverStats* driverStats;
#property (nonatomic,retain) DriverStats* driverStats;
[driverStats parseRow:dictionary];
If I add [arName release] in my class, when I exit from parseRow method, I have the EXC_BAD_ACCESS error.... but it's wrong?? I used array and after I released... I think that the error will be if I didn't release the pointer.. or not???
thanks in advance
The problem is easy to solve. Your NSArray *array only have 0 retainCount. Because you use a factory method componentsSeparatedByString:, it returns you an autoreleased array already. So, you don't need to release your array anymore.
Another thing you need to care about is the setDriverName: and setDriverSurname:, make sure you retain/copy the object there otherwise, when the array is released, those objects are also released and EXEC_BAD_ACCESS again
I have a mutableArray that I fill up with objects. When I try to refill the array, I first use removeAllObjects - which produces a memory leak...
The properties of the object are synthesized, retained and released on dealloc.
The Array is initialized on viewDidLoad like this:
theArray = [[NSMutableArray alloc] initWithCapacity:10];
... and it's retained and synthesized. (#property (nonatomic, retain) NSMutableArray *theArray)
I'm adding the objects in a while-loop like this:
myObject *theObject = [[myObject alloc] init];
theObject.someProperty = #"theprop";
[theArray addObject: theObject];
[theObject release];
then on the next call of the method, I remove all objects like this:
[theArray removeAllObjects];
That's where the leak occurs. If I comment this line out, the leak doesn't appear. So I guess I'm doing something wrong in my object?
Seems like the problem is solved...
a) I didn't realize, that when I use instruments, the app isn't compiled before launch - thus, some of the changes I made were not taking into effect, when using instruments. So now I first build and run after a change and then run it in instruments.
b) thus, I don't really know what solved the problem. But it might be that I had the dealloc-method in my object wrong.
I was using:
[super dealloc];
[myProperty release];
instead of the other way around:
[myProperty release];
[super dealloc];
Thanks for the help, though!
Does myObject have any retained properties? If so, are you setting them to nil in the dealloc message? If not, when it is dealloced it won't release the objects that its properties are set to.
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.