Philippe Renaud
asked on
NSMutableArray in Objective-C
Hello EE-Mac,
I am doing an app in XCode with objective-C.
My problem is as follow:
I have a code that read a web service that receive some data (see snippet 1)
ok so here I am used to .NET Technology. when you see the line action:@selector(handleGet Presentati ons:)
I thought XCode would go inside that BEFORE going to the next line wich is a NSLog then the return. But I see that it goes to the NSLog before entering the handleGetPresentation. so my finalList count is 0 and it returns nothing.
I dont understand how to return my array with an action:@selector
Is it possible maybe to instead of writing (void) in my handleGetPresentations to return (NSMustableArray*) ?
if so, I dont understand how in loadPresentations to retrive that return value.
any idea??
I am doing an app in XCode with objective-C.
My problem is as follow:
I have a code that read a web service that receive some data (see snippet 1)
ok so here I am used to .NET Technology. when you see the line action:@selector(handleGet
I thought XCode would go inside that BEFORE going to the next line wich is a NSLog then the return. But I see that it goes to the NSLog before entering the handleGetPresentation. so my finalList count is 0 and it returns nothing.
I dont understand how to return my array with an action:@selector
Is it possible maybe to instead of writing (void) in my handleGetPresentations to return (NSMustableArray*) ?
if so, I dont understand how in loadPresentations to retrive that return value.
any idea??
@synthesize listData;
...
-(NSMutableArray*)loadPresentations{
NSLog(@"Test");
SDZService* service = [[SDZService alloc]init];
[service GetPresentations:self action@selector(handleGetPresentations:)];
NSLog(@"count is, %i", finalList.count);
return finalList;
}
-(void) handleGetPresentations:(id)value {
if ([value isKindOfClass:[NSError class]]) {
NSLog(@"This is an error: %@", value);
return;
}
if ([value isKindOfClass:[SoapFault class]]) {
NSLog(@"This is a fault: %@", value);
return;
}
NSMutableArray* a = value;
NSMutableArray* finalArray = [[NSMutableArray alloc] init];
for (SDZPresentation* p in a){
Presentations* pr = [[Presentations alloc] init];
pr.presentationID = p.ID;
pr.presentationDesc = p.Description;
pr.presentationComments = p.Comments;
[finalArray addObject:pr];
[pr release];
}
self.listData = [[NSMutableArray alloc] initWithArray:finalArray];
[finalArray release];
//return listData;
finalList = listData;
NSLog(@"count is %i", finalList.count);
}
ASKER
ok so mmm... not sure how to call my service GetPresentations then...
It's hard to provide assistance when custom classes are involved. What is the SDZService class, and what does it do? Just as well, as you allocated that class, it should be released or autoreleased before the method ends.
ASKER
Actually the class came from www.sudzc.com
it creates classes for you with a given .net web service
the class is in the snippet (interface, implementation)
so its simply some SoapActions I see that there is a GetPresentations: without _action to be invoke I might need to call that, im still new to all this thats why I came here actually.
You are right about the release, I forgot.
it creates classes for you with a given .net web service
the class is in the snippet (interface, implementation)
so its simply some SoapActions I see that there is a GetPresentations: without _action to be invoke I might need to call that, im still new to all this thats why I came here actually.
You are right about the release, I forgot.
@interface SDZService1 : SoapService
/* Returns NSMutableArray*. */
- (SoapRequest*) GetPresentations: (id <SoapDelegate>) handler;
- (SoapRequest*) GetPresentations: (id) target action: (SEL) action;
+ (SDZService1*) service;
+ (SDZService1*) serviceWithUsername: (NSString*) username andPassword: (NSString*) password;
@end
/* Returns NSMutableArray*. */
- (SoapRequest*) GetPresentations: (id <SoapDelegate>) handler
{
return [self GetPresentations: handler action: nil];
}
- (SoapRequest*) GetPresentations: (id) _target action: (SEL) _action
{
NSMutableArray* _params = [NSMutableArray array];
NSString* _envelope = [Soap createEnvelope: @"GetPresentations" forNamespace: self.namespace withParameters: _params withHeaders: self.headers];
SoapRequest* _request = [SoapRequest create: _target action: _action service: self soapAction: @"http://www.fashionize.ca/GetPresentations" postData: _envelope deserializeTo: [[SDZArrayOfPresentation alloc] autorelease]];
[_request send];
return _request;
}
Here's an idea. There is a method called [self performSelectorOnMainThrea d... waitUntilDone:YES];
Would you be able to put your [service getPresentations...] method in a new selector, and call it whilst waitingUntilDone?
Would you be able to put your [service getPresentations...] method in a new selector, and call it whilst waitingUntilDone?
-(NSMutableArray *)... {
[self performSelectorOnMainThread:@selector(callOtherMethod) withObject:nil waitUntilDone:YES];
}
-(void)callOtherMethod {
SDZService* service = [[SDZService alloc]init];
[service GetPresentations:self action@selector(handleGetPresentations:)];
}
ASKER
Well I jsut tried, and if I do a NSLog(@"count %i", finalList.count); wich by the way finalList a static NSMutableArray at the top, right after the #imports....
it still count : 0
but the count is 3 inside handleGetPresentations.
[self performSelectorOnMainThrea d:@selecto r(callOthe rMethod) withObject:nil waitUntilDone:YES];
the count is 0....
did I misunderstood your idea? ..
it still count : 0
but the count is 3 inside handleGetPresentations.
[self performSelectorOnMainThrea
the count is 0....
did I misunderstood your idea? ..
Could you find the time that the NSLogs are called? I would like to see if it waits to run the other selector and then moves on (because it should...). I am thinking that it is an issue with setting the variables instead of method call times.
Have you considered using Properties to handle the finalList array?
Have you considered using Properties to handle the finalList array?
I ran a test myself, with this code:
This is what the log showed:
So, we have established that it waits to finish the method before moving on. Therefore, I would think that it is an issue with the way that you receive finalList.
In your .h file, do you have a property for it?
(in dealloc)
Then, to set finalList, do this:
Then, to retrieve it, do this:
-(void)test1 {
NSLog(@"This is the Test1 method.");
[self performSelectorOnMainThread:@selector(test2) withObject:nil waitUntilDone:YES];
NSLog(@"This is the Test1 method end.");
}
-(void)test2 {
NSLog(@"This is the Test2 method.");
}
This is what the log showed:
2011-08-22 12:10:48.944 Test[20046:10d03] This is the Test1 method.
2011-08-22 12:10:48.955 Test[20046:10d03] This is the Test2 method.
2011-08-22 12:10:48.956 Test[20046:10d03] This is the Test1 method end.
So, we have established that it waits to finish the method before moving on. Therefore, I would think that it is an issue with the way that you receive finalList.
In your .h file, do you have a property for it?
@property (nonatomic, retain) NSMutableArray *finalList;
@synthesize finalList;
(in dealloc)
[finalList release], finalList = nil;
Then, to set finalList, do this:
[self setFinalList:listData];
Then, to retrieve it, do this:
NSLog(@"%@",[self finalList]);
ASKER
my NSLog right after the line
[self performSelectorOnMainThrea d:@selecto r(callOthe rMethod) withObject:nil waitUntilDone:YES];
is : 2011-08-22 13:10:40:538 just after waitUntilDone Count: 0
then I have:
2011-08-22 13:10:40:565 inside handleGetPresentations count: 3
for the array, I have already a @synthesize listData;
in the interface its a property nonatomic, retain NSMustableArray*
Actually I put a static finalList because I was going empty on ideas for that problem.
I guess I could just instead of doing [finalList addObject:pr]; I could take the listData and do [listData adDObject:pr]; ?
[self performSelectorOnMainThrea
is : 2011-08-22 13:10:40:538 just after waitUntilDone Count: 0
then I have:
2011-08-22 13:10:40:565 inside handleGetPresentations count: 3
for the array, I have already a @synthesize listData;
in the interface its a property nonatomic, retain NSMustableArray*
Actually I put a static finalList because I was going empty on ideas for that problem.
I guess I could just instead of doing [finalList addObject:pr]; I could take the listData and do [listData adDObject:pr]; ?
ASKER
Wait let me see something I might have did an error with your code, by right back
ASKER
Ok so now I have this:
result is..:
2011-08-22 13:20:44.138 Fashionize[747:207] Test2
2011-08-22 13:20:44.140 Fashionize[747:207] jsut after waitUntilDone 0
2011-08-22 13:20:44.169 Fashionize[747:207] inside handleGetPresentations 0
result is..:
2011-08-22 13:20:44.138 Fashionize[747:207] Test2
2011-08-22 13:20:44.140 Fashionize[747:207] jsut after waitUntilDone 0
2011-08-22 13:20:44.169 Fashionize[747:207] inside handleGetPresentations 0
@implementation PresentationLoader
@synthesize listData;
-(NSMutableArray*)loadPresentation{
[self performSelectorOnMainThread:@selector(handleSelectorGetPresentations) withObject:nil waitUntilDone:YES];
NSLog(@"just after waitUntilDone %i", finalList.count);
return finalList;
}
-(void) handleSelectorGetPresentations{
NSLog(@"Test2");
SDZService1* service = [[[SDZService1 alloc]init] autorelease];
[service GetPresentations:self action:@selector(handleGetPresentations:)];
}
-(void) handleGetPresentations:(id)value {
if ([value isKindOfClass:[NSError class]]) {
NSLog(@"This is an error: %@", value);
return;
}
if ([value isKindOfClass:[SoapFault class]]) {
NSLog(@"This is a fault: %@", value);
return;
}
NSMutableArray* a = value;
NSMutableArray* finalArray = [[NSMutableArray alloc] init];
for (SDZPresentation* p in a){
Presentations* pr = [[Presentations alloc] init];
pr.presentationID = p.ID;
pr.presentationDesc = p.Description;
pr.presentationComments = p.Comments;
[listData addObject:pr];
[pr release];
}
self.listData = [[NSMutableArray alloc] initWithArray:finalArray];
[finalArray release];
//return listData;
//finalList = listData;
NSLog(@"inside handleGetPresentations %i", finalList.count);
}
-(void) dealloc{
[listData release];
[super dealloc];
}
@end
ASKER
sorry I wrote finalList but even If I replace with listData it still 0...
Damn Im lost now.
Damn Im lost now.
Basically, what I see happening is that you call the [service GetPresentations:...], and then that method ends. Do you know if [service getPresentations:...] calls anything on a new thread? Have you thought about implementing delegation to let the caller know when you are done downloading the data?
What you could do is call the loadPresentation method, then have that call the SDZService. From there, you could have it send out a message to the delegates when handleGetPresentations finishes.
What you could do is call the loadPresentation method, then have that call the SDZService. From there, you could have it send out a message to the delegates when handleGetPresentations finishes.
ASKER
I dont think it goes on new threads.
For the rest of your comment... Not sure to understand.
If I recap.. I already call loadPresentation. thats fine for now.
If I call the SDZService with the action:@selector yes it will load my property Array inside it (because the NSLog inside count is 3) ..
what do you mean by sending a message to the delegates
For the rest of your comment... Not sure to understand.
If I recap.. I already call loadPresentation. thats fine for now.
If I call the SDZService with the action:@selector yes it will load my property Array inside it (because the NSLog inside count is 3) ..
what do you mean by sending a message to the delegates
Basically, there will be no way to do that you are setting up as when it downloads, it will be multithreading as to not slow down your application. What I am suggesting is to implement delegation, so when downloading finishes, you can notify the class that called the download and give the relevant information.
ASKER
Alright I see.
So finally, what should I type in google to have some example of that, delegation ? is there a reference name for when you say : "when download finishes you do that and that.." in other words, how can I know it finishes?
So finally, what should I type in google to have some example of that, delegation ? is there a reference name for when you say : "when download finishes you do that and that.." in other words, how can I know it finishes?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks
ASKER
hey!
im almost there. I think one last problem. see:
https://www.experts-exchange.com/questions/27269391/Trouble-with-delegate.html
im almost there. I think one last problem. see:
https://www.experts-exchange.com/questions/27269391/Trouble-with-delegate.html
I would recommending housing all of the necessary code in your -(NSMutableArray*)loadPres