开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜