How to retrieve and view the elements from the NSMutableArray
I am trying some examples from the book "Objective C for Dummies". I tried to retrieve the elements with this code below but in vain. All are considered as Objects in the NSMutableArray. But I don't know how to retrieve the elements using the objects.
main.m
#import <Foundation/Foundation.h>
#import "BudObj.h"
#import "Transaction.h"
int main(int argc, char *argv[]) {
Budget* europeBudget=[Budget new];
NSMutableArray *transactions=[[NSMutableArray alloc] initWithCapacity:10];
[europeBudget createBudget:1000.00 withExchangeRate:1.2500];
Transaction* aTransaction;
aTransaction = [Transaction new];
for(int n=1;n<2;n++){
aTransaction = [[Transaction alloc] init];
[aTransaction createTransaction:n*100 ofType:cash];
[transactions addObject:aTransaction];
[aTransaction release];
}
int n=1;
while (n<3) {
aTransaction = [[Transaction alloc]init];
[aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:aTransaction];
[aTransaction release];
n++;
}
do{
aTransaction = [[Transaction alloc]init];
[aTransaction createTransaction:n*100 ofType:cash];
[transactions addObject:aTransaction];
[aTransaction release];
n++;
}while (n<=3);
NSLog(@"\nNumber of elements in an array:%i",[transactions count]);
int c;
c=[transactions count];
NSLog(@"\nThe Elements are:\n");
for(int i=0;i<c;i++){
NSLog(@"%@",[transactions objectAtIndex:i]);
}
for(Transaction *aaTransaction in transactions){
switch ([aTransaction returnType]) {
case cash:
[europeBudget spendDollars:[aaTransaction returnAmount]];
break;
case credit:
[europeBudget changeForeignCurrency:[aaTransaction returnAmount]];
break;
default:
break;
}
}
[transactions release];
[europeBudget release];
return 0;
}
BudObj.h
#import <Foundation/Foundation.h>
@interface
Budget : NSObject {
float exchangeRate;
double budget;
double exchangeTransaction;
}
- (void) createBudget: (double) aBudget withExchangeRate: (float) anExchangeRate;
- (void) spendDollars: (double) dollars;
- (void) changeForeignCurrency: (double) foreignCurrency;
@end
BudObj.m
#import <Foundation/Foundation.h>
#import "BudObj.h"
#import "Transaction.h"
@implementation Budget
- (void) createBudget: (double) aBudget withExchangeRate: (float) anExchangeRate{
budget = aBudget;
exchangeRate = anExchangeRate;
}
- (void) spendDollars:(double)dollars{
budget = budget - dollars;
NSLog(@"Converting %0.2f US Dollars into Foreign Currency leaves $%0.2f",dollars,budget);
}
- (void) changeForeignCurrency:(double)foreignCurrency{
exchangeTransacti开发者_如何学编程on = foreignCurrency * exchangeRate;
budget = budget - exchangeTransaction;
NSLog(@"Charging %0.2f in Foreign Currency leaves $%0.2f",foreignCurrency,budget);
}
@end
Transaction.h
#import <Cocoa/Cocoa.h>
typedef enum{cash,credit} transactionType;
@interface Transaction : NSObject {
transactionType type;
double amount;
}
-(void)createTransaction:(double)theAmount ofType:(transactionType)theType;
-(double)returnAmount;
-(transactionType)returnType;
@end
Transaction.m
#import "Transaction.h"
@implementation Transaction
-(void)createTransaction:(double)theAmount ofType:(transactionType)theType{
type=theType;
amount=theAmount;
}
-(double)returnAmount{
return amount;
}
-(transactionType)returnType{
return type;
}
@end
Output
The Elements are:
2011-04-15 18:12:11.039 BudObj.m[2180:a0f] <Transaction: 0x10010c950> //Could not retreive the data from the array it's showing up some address
2011-04-15 18:12:11.039 BudObj.m[2180:a0f] <Transaction: 0x100104fe0> //
2011-04-15 18:12:11.040 BudObj.m[2180:a0f] <Transaction: 0x100106c60> //
2011-04-15 18:12:11.040 BudObj.m[2180:a0f] <Transaction: 0x100106d00> //
2011-04-15 18:12:11.041 BudObj.m[2180:a0f] Converting 100.00 US Dollars into Foreign Currency leaves $900.00
2011-04-15 18:12:11.041 BudObj.m[2180:a0f] Converting 100.00 US Dollars into Foreign Currency leaves $800.00
2011-04-15 18:12:11.041 BudObj.m[2180:a0f] Converting 200.00 US Dollars into Foreign Currency leaves $600.00
2011-04-15 18:12:11.042 BudObj.m[2180:a0f] Converting 300.00 US Dollars into Foreign Currency leaves $300.00
for (Transaction* transaction in transactions) {
//do stuff here, or just print the object with something like the code below
NSLog(@"Transaction: %@", transaction);
}
Of course, when you have code like this:
[aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:aTransaction];
...you are not actually storing the newly created transaction in the array. You are just storing the variable aTransaction
multiple times. You may have better luck with something like:
Transaction* nextTransaction = [aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:nextTransaction];
Edit:
You may have more luck with:
#import <Foundation/Foundation.h>
#import "BudObj.h"
#import "Transaction.h"
int main(int argc, char *argv[]) {
Budget* europeBudget=[[Budget alloc] init];
NSMutableArray *transactions=[[NSMutableArray alloc] initWithCapacity:10];
[europeBudget createBudget:1000.00 withExchangeRate:1.2500];
Transaction* aTransaction = nil;
for(int n=1;n<2;n++){
//this adds 1 transaction to the array
aTransaction = [[[Transaction alloc] init] autorelease];
[aTransaction createTransaction:n*100 ofType:cash];
[transactions addObject:aTransaction];
}
int n=1;
while (n<3) {
//this adds 2 transactions to the array
aTransaction = [[[Transaction alloc] init] autorelease];
[aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:aTransaction];
n++;
}
do{
//this adds 1 transaction to the array
aTransaction = [[[Transaction alloc] init] autorelease];
[aTransaction createTransaction:n*100 ofType:cash];
[transactions addObject:aTransaction];
n++;
}while (n<=3);
//there should be 4 elements in the array now
NSLog(@"\nNumber of elements in an array:%i",[transactions count]);
int c;
c=[transactions count];
NSLog(@"\nThe Elements are:\n");
for(int i=0;i<c;i++){
Transaction* trans = [transactions objectAtIndex:i];
NSLog(@"Transaction %d: %@; type=%d, amount=%f", i, trans, [trans returnType], [trans returnAmount]);
}
for(Transaction *aaTransaction in transactions){
switch ([aTransaction returnType]) {
case cash:
[europeBudget spendDollars:[aaTransaction returnAmount]];
break;
case credit:
[europeBudget changeForeignCurrency:[aaTransaction returnAmount]];
break;
default:
break;
}
}
[transactions release];
[europeBudget release];
return 0;
}
The address that you see in your output doesn't mean that the program couldn't find the Transaction
in the array. In fact, it means the exact opposite. The address is the address in memory of your Transaction
instance. The reason it gets printed as an address is because that is the default behavior when printing an NSObject
instance. Your class is not overriding this default behavior, so you get the memory address when you print it.
If you want to override this default behavior, you can do something like:
#import "Transaction.h"
@implementation Transaction
//override the 'description' method to change how your object prints
-(NSString*)description {
NSString* friendlyType = theType == cash ? @"cash" : @"credit";
return [NSString stringWithFormat:@"Transaction: type=%@, amount=%f", friendlyType, amount];
}
-(void)createTransaction:(double)theAmount ofType:(transactionType)theType{
type=theType;
amount=theAmount;
}
-(double)returnAmount{
return amount;
}
-(transactionType)returnType{
return type;
}
@end
You are already getting the objects out of the array in the last 4 lines of your code.
When you use [transactions objectAtIndex:i]
that will return the i'th
transaction
object in the array.
The issue you are having is that you're outputting your object as an integer (i
) in your NSLog
. Instead you should use @
.
Another issue is that objects in Objective-C are reference types. That means that when you assign an object to another object, say:
Transaction* transA = [[Transaction alloc] init];
Transaction* transB = [[Transaction alloc] init];
transB = transA;
The first two lines create two separate objects. But the third line assigns transB
as a reference to transA
. That is to say, they are the same object. Also, this leaks memory since transB
no longer points to the original object.
While I'm not 100% sure how your object creation works, the lines similar to [aTransaction createTransaction:n*100 ofType:cash];
are assigning the values to the same object (aTransaction
). This means, most likely all of the objects contained within your array are pointers to the same object. Moreover, these could be leaking memory if they aren't returning autoreleased objects.
An easy way to log elements in an NSArray
or NSMutableArray
(or probably any collection type) is to simply do:
NSArray* someArray = [NSArray array];
// Add items here.
NSLog(@"SomeArray: %@", someArray);
The output will automatically be formatted for you.
精彩评论