#objective-c #nsmutablearray
#objective-c #nsmutablearray
Вопрос:
Я пробую несколько примеров из книги «Objective 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
Ответ №1:
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];
Редактировать:
Возможно, вам повезет больше с:
#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
Комментарии:
1. Я тоже пробовал это. Я получаю некоторый адрес, распечатанный в качестве выходных данных.
2. @Beata Jane — вероятно, это адрес экземпляров вашего объекта. Если вы предоставите некоторые подробности о том, какие поля / свойства существуют в
Transaction
объекте, мы можем предоставить несколько лучших примеров того, как печатать их осмысленным способом.3. @aroth-Я отредактировал код и предоставил полную программу выше. пожалуйста, ознакомьтесь с ней.
4. @Beata Jane — Извините за задержку, я обновил свой ответ. Надеюсь, это поможет прояснить ситуацию.
Ответ №2:
Вы уже извлекаете объекты из массива в последних 4 строках вашего кода.
При использовании [transactions objectAtIndex:i]
этого будет возвращен i'th
transaction
объект в массиве.
Комментарии:
1. Я помещаю это в цикл for, поэтому должен отображаться объект с индексом 0,1,2, независимо от того, какое количество. Но я все еще не мог понять, как извлечь элементы из массива.
Ответ №3:
Проблема, с которой вы сталкиваетесь, заключается в том, что вы выводите свой объект как целое число ( 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
or NSMutableArray
(или, возможно, в любом типе коллекции) — это просто сделать:
NSArray* someArray = [NSArray array];
// Add items here.
NSLog(@"SomeArray: %@", someArray);
Выходные данные будут автоматически отформатированы для вас.
Комментарии:
1. Я пытался с тем же, что вы сказали, но, похоже, он отображает какой-то адрес