Как получить и просмотреть элементы из NSMutableArray - PullRequest
0 голосов
/ 14 апреля 2011

Я пробую несколько примеров из книги "Цель C для чайников".Я попытался получить элементы с этим кодом ниже, но тщетно.Все они рассматриваются как объекты в NSMutableArray.Но я не знаю, как извлечь элементы, используя объекты.

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{
    exchangeTransaction = 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

Выход

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

Ответы [ 3 ]

1 голос
/ 14 апреля 2011
for (Transaction* transaction in transactions) {
   //do stuff here, or just print the object with something like the code below
   NSLog(@"Transaction:  %@", transaction);
}

Конечно, когда у вас есть такой код:

[aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:aTransaction];

... вы на самом деле не храните вновь созданную транзакцию в массиве. Вы просто храните переменную aTransaction несколько раз. Возможно, вам повезет больше с чем-то вроде:

Transaction* nextTransaction = [aTransaction createTransaction:n*100 ofType:credit];
[transactions addObject:nextTransaction];

Edit:

У вас может быть больше удачи с:

#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;
}

Адрес, который вы видите в выходных данных, не означает, что программе не удалось найти Transaction в массиве. На самом деле это означает прямо противоположное. Адрес - это адрес в памяти вашего экземпляра Transaction. Причина, по которой он печатается как адрес, заключается в том, что при печати экземпляра NSObject это поведение по умолчанию. Ваш класс не переопределяет это поведение по умолчанию, поэтому вы получаете адрес памяти при его печати.

Если вы хотите переопределить это поведение по умолчанию, вы можете сделать что-то вроде:

#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
0 голосов
/ 14 апреля 2011

Вы уже получаете объекты из массива в последних 4 строках вашего кода.

Когда вы используете [transactions objectAtIndex:i], это вернет объект i'th transaction в массиве.

0 голосов
/ 14 апреля 2011

Проблема, с которой вы столкнулись, заключается в том, что вы выводите свой объект как целое число (i) в вашем NSLog.Вместо этого вы должны использовать @.

Другая проблема заключается в том, что объекты в Objective-C являются ссылочными типами.Это означает, что когда вы назначаете объект другому объекту, говорите:

Transaction* transA = [[Transaction alloc] init];
Transaction* transB = [[Transaction alloc] init];

transB = transA;

Первые две строки создают два отдельных объекта.Но третья строка присваивает transB как ссылку на transA.То есть они один и тот же объект .Кроме того, это приводит к утечке памяти, поскольку transB больше не указывает на исходный объект.

Хотя я не уверен на 100%, как работает создание вашего объекта, строки, подобные [aTransaction createTransaction:n*100 ofType:cash];, присваивают значениятот же объект (aTransaction).Это означает, что, скорее всего, все объекты, содержащиеся в вашем массиве, являются указателями на один и тот же объект.Более того, это может привести к утечке памяти, если они не возвращают автоматически выпущенные объекты.


Простой способ зарегистрировать элементы в NSArray или NSMutableArray (или, возможно, любой тип коллекции) состоит в следующем:

NSArray* someArray = [NSArray array];
// Add items here.
NSLog(@"SomeArray: %@", someArray);

Вывод будет автоматическиотформатирован для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...