2012-07-05 41 views
16

Tôi đang làm việc với trò chơi có quái vật. Mỗi người có một danh sách các số liệu thống kê tất cả sẽ được ints. Tôi có thể thiết lập mỗi stat như biến riêng của nó nhưng tôi muốn giữ chúng trong một NSDictionary vì chúng đều liên quan. Tôi đang gặp sự cố khi tôi cố gắng thay đổi giá trị của từng chỉ số.NSDictionary Với Giá trị Số nguyên

Những gì tôi có:

-(id) init { 
    self = [super init]; 
    if(self) { 
     stats = [NSDictionary dictionaryWithObjectsAndKeys: 
       @"Attack", 0, 
       @"Defense", 0, 
       @"Special Attack", 0, 
       @"Special Defense", 0, 
       @"HP", 0, nil]; 
    } 
    return self; 
} 

Những gì tôi muốn làm

-(void) levelUp { 
    self.level++; 
    [self.stats objectForKey:@"Attack"] += (level * 5); 
    [self.stats objectForKey:@"Defense"] += (level * 5); 
    [self.stats objectForKey:@"Special Attack"] += (level * 5); 
    [self.stats objectForKey:@"Special Defense"] += (level * 5); 
    [self.stats objectForKey:@"HP"] += (level * 5); 
} 

Lỗi Tôi Bắt

Arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI 

S o có vẻ như rõ ràng với tôi rằng lý do tôi nhận được vấn đề là tôi nhận được một đối tượng được trả về từ objectForKey thay vì một số nguyên. Vì vậy, tôi đã cố gắng để làm phương pháp intValue trên đối tượng tôi nhận được nhưng điều đó đã cho tôi một lỗi khác, cụ thể là:

Assigning to 'readonly' return result of an objective-c message not allowed 

Tôi hết ý tưởng để khắc phục điều này. Bất kỳ giúp đỡ? Nó sẽ là tốt hơn để chỉ cần từ bỏ ý tưởng để lưu trữ tất cả chúng lại với nhau và chỉ sử dụng một tài sản int cho mỗi stat?

Trả lời

53
  1. Bạn chỉ có thể lưu trữ các đối tượng, không phải nguyên thủy, trong các lớp sưu tập Cocoa, do đó, để lưu trữ các số bạn cần sử dụng các đối tượng NSNumber.
  2. Bạn cần sử dụng NSMutableDictionary nếu bạn muốn thay đổi nội dung sau này.
  3. Cuộc gọi của bạn tới dictionaryWithObjectsAndKeys có các khóa và giá trị được đảo ngược.
  4. Đối tượng stats của bạn không được giữ lại, vì vậy nó sẽ được phát hành vào lần sau vòng lặp chạy (nếu bạn đang sử dụng tính năng tham chiếu thủ công).

Bạn muốn:

stats = [[NSMutableDictionary dictionaryWithObjectsAndKeys: 
    [NSNumber numberWithInt:0], @"Attack", 
    [NSNumber numberWithInt:0], @"Defense", 
    [NSNumber numberWithInt:0], @"Special Attack", 
    [NSNumber numberWithInt:0], @"Special Defense", 
    [NSNumber numberWithInt:0], @"HP", 
    nil] retain]; 

Để thay đổi các giá trị bạn cần phải tạo ra một đối tượng mới NSNumber khi họ không thể thay đổi, vì vậy cái gì đó như:

NSNumber *num = [stats objectForKey:@"Attack"]; 
NSNumber *newNum = [NSNumber numberWithInt:[num intValue] + (level * 5)]; 
[stats setObject:newNum forKey:@"Attack"]; 

Tất cả khá tẻ nhạt nếu bạn hỏi tôi; phải có một cách dễ dàng hơn, ví dụ như thế nào về việc tạo ra một lớp Objective-C để lưu trữ và thao tác công cụ này?câu trả lời

+0

Tôi không phải lo lắng về việc giữ lại nếu tôi đang sử dụng ARC phải không? Ngoài ra, bạn đang phải này trông hơi tẻ nhạt ... có lẽ tôi sẽ thử một lớp học thay thế. – CaldwellYSR

+0

@CaldwellYSR Vâng, bạn nói đúng - không cần phải lo lắng về việc "giữ lại" nếu bạn đang sử dụng ARC. – trojanfoe

+0

Cảm ơn lời khuyên, tôi không biết tại sao tôi không nghĩ đến việc làm cho họ thành một lớp học. Nó sẽ làm cho rất nhiều thứ dễ dàng hơn trong thời gian dài. – CaldwellYSR

7

NSDictionary s store NSObject* s. Để sử dụng chúng với các giá trị số nguyên, bạn không may cần sử dụng một cái gì đó như NSNumber. Vì vậy, khởi tạo của bạn sẽ trông như thế:

-(id) init { 
    self = [super init]; 
    if(self) { 
     stats = [NSDictionary dictionaryWithObjectsAndKeys: 
       @"Attack", [NSNumber numberWithInt:0], 
       @"Defense", [NSNumber numberWithInt:0], 
       @"Special Attack", [NSNumber numberWithInt:0], 
       @"Special Defense", [NSNumber numberWithInt:0], 
       @"HP", [NSNumber numberWithInt:0], nil]; 
    } 
    return self; 
} 

Sau đó, bạn sẽ phải khôi phục lại theo số:

NSNumber *atk = [self.stats objectForKey:@"Attack"]; 
int iAtk = [atk intValue]; 
[self.stats setObject:[NSNumber numberWithInt:iAtk] forKey:@"Attack"]; 

EDIT

Tất nhiên, để làm được điều này, self.stats nhu cầu để là một số NSMutableDictionary

+0

Wow Làm thế nào mà tôi hoàn toàn quên rằng bạn không thể thay đổi giá trị mà không có chúng có thể thay đổi được. Khi tôi lấy NSNumber, tôi có thể thêm một số nguyên vào NSNumber đó không? – CaldwellYSR

+2

Thứ tự của các giá trị và khóa trong 'dictionaryWithObjectsAndKeys' được đảo ngược và' số liệu thống kê' không được giữ lại. – trojanfoe

4

Thích ứng @ trojanfoe cho hiện đại Objective-C với đẹp đường cú pháp:

stats = [@{@"Attack"   : @0, 
      @"Defense"   : @0, 
      @"Special Attack" : @0, 
      @"Special Defense" : @0, 
      @"HP"    : @0} mutableCopy]; 

Và để cập nhật một giá trị:

stats[@"Attack"] = @([stats[@"Attack"] intValue] + (level * 5)); 
Các vấn đề liên quan