2013-08-22 2 views
0

Я создаю NSMutableArray, который мне нужен, пока работает мое приложение, позволяет называть его suseranArray сразу после @implementation моего основного класса. Этот массив будет содержать несколько объектов класса Вассал. Вассала просто:Элементы, исчезающие из массива в массиве

1) NSMutableString 2) Другой NSMutableString 3) NSMutableArray 4) Еще один NSMutable массив

Каждый вассальным создан также необходим для жизни приложения, и они никогда не изменится ,

Эти объекты создаются как (сохраняющие) свойства в файле .h, синтезируются в файле .m, и каждый присваивает alloc + init всякий раз, когда объект Vassal создается во время функции init. Каждый вассал имеет данные, заполненные и хранящиеся в массиве сюзерена. у 3-го элемента всегда есть несколько элементов, и после появления ошибки я помещаю строку, чтобы проверить, если она когда-либо пуста, но она никогда не бывает, и жизнь хороша.

Теперь, когда необходим определенный объект Vassal, мы пытаемся получить доступ к его третьему свойству, чтобы извлечь данные там, а иногда этот массив пуст ... Я проверил, чтобы увидеть, исчезло ли оно каким-то образом, но это всегда там, на отладочном, имея хороший адрес, такой как 0x2319f8a0, который имеет смысл, поскольку NSMutableString чуть выше его по адресу 0x2319fb40 - (я ожидал 00000000 после много головной боли). Что происходит? Я в голове, я создаю объекты RETAINED, которые сохраняют данные, помещенные по умолчанию, и этот объект помещается внутри другого, но каким-то образом данные внутри массива исчезают. Какой возможный сценарий может привести к этому? Спасибо за ваше время :)

Примечания: последний массив в настоящее время только имеет один пункт на данном этапе развития, и как ни странно, что один пункт никогда не хватает, несмотря на два массива, являющихся «братья»

Vassal.h 
@interface Vassal : NSObject 
@property (retain) NSMutableString *wordBody; 
@property (retain) NSMutableString *wordCode; 
@property (retain) NSMutableArray *wordRelations; 
@property (retain) NSMutableArray *wordLinks; 
@end 

Vassal.m 
@implementation Vassal:NSObject 
@synthesize wordBody; 
@synthesize wordCode; 
@synthesize wordRelations; 
@synthesize wordLinks; 
-(NSObject*) init 
{ 
    if(self=[super init]) 
    { 
     wordBody=[[NSMutableString alloc] init]; 
     wordCode=[[NSMutableString alloc] init]; 
     wordRelations=[[NSMutableArray alloc] init]; 
     wordLinks=[[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

//Somewhere in Suseran: 
-(void)fillStuff 
{ 
    ... 
    Vassal *vassal=[Vassal new]; 
    for (int i=0;i<[originalDataString length];i++) 
    { 
     ... 
     [vassal.wordRelations addObject:anItem]; 
     ... 
    } 
    int errorTest=[vassal.wordRelations count]; 
    if (errorTest==0) 
    { 
     //breakpoint here. Program NEVER comes here 
    } 
    [bigArrayOfVassals addObject:vassal]; 
} 
//these arrays are never touched again but here: 
-(void) getVassalstuff:(NSMutableString*)codeOfDesiredVassal 
{ 
    Vassal *aVassal; 
    for (int i=0;i<[bigArrayOfVassals count];i++) 
    { 
      aVassal=bigArrayOfVassals[i]; 
      if ([codeOfDesiredVassal isEqualToString:aVassal.wordCode) 
      { 
        int errorTest=[aVassal.wordRelations count]; 
        if (errorTest==0) 
        { 
         //yay! this breakpoint sometimes is hit, sometimes not, 
         //depending on code's mood. Why is this happening to me? :,(
        } 
      } 
    } 
} 
+1

Линия кода лучше, чем пять строк объяснений :-) – dasblinkenlight

+0

Нет причин ожидать, что «близкие» элементы будут иметь «закрытые» адреса. Куча не работает. –

+0

(Я предполагаю, что у вас есть копия указателя на массив где-то еще, и вы изменяете массив через эту копию указателя. Вам нужно понять разницу между указателем (адресом) и самим объектом (дом по этому адресу). У вас может быть много указателей на данный объект, и все изменения, сделанные с помощью одного, видны всем.) –

ответ

1

Я вижу, что у вас есть свойства, которые изменяются (что само по себе является плохими идеями, за исключением конкретных случаев) и что вы их сохраняете.

Mutability означает, что если вы задали массив как свойство, основанное на каком-либо другом массиве, и если этот исходный массив был изменен, массив в вашем свойстве также будет изменен. Может быть, и я не знаю, потому что вы не показали какой-либо код, который вы опорожнение исходного массива, и, таким образом, изменяя массив у вас есть как свойство

Решения:

Моего предпочтительное решения заключается в использовании неизменных версий этих классов для ваших свойств; NSString, NSArray и вместо того, чтобы сохранить использование копии

Второе решение оставить свойства, как изменчивый, но писать пользовательские сеттер для каждого из них, который хранит mutableCopy объекта, который вы передаете в.

В оба этих случая, ваше свойство будет копией объекта, используемого для установки свойства, так что если объект изменен вне вашего класса, это не повлияет на свойства вашего класса.

отредактирован, чтобы добавить, после комментария

Если вы объявляете вашу собственность как

@property (copy) NSArray wordRelations; 

Тогда просто писать

vassal wordArray = tempArray; 

будет делать то же самое, и чище, и многое другое читаемый ..

+0

Попробуй все это, спасибо. После ввода начального значения данные не изменяются. Массивы - это всего лишь копия файла данных, который никогда не изменяется после их заполнения. На самом деле я был * этим * близок к простому чтению информации из файла вместо использования массивов - «сделайте это сейчас, оптимизируйте позже». –

+1

Если они никогда не меняются после их добавления - там не имеет смысла использовать их как изменяемые. – Abizern

+0

Ну, я сменил wordRelations на NSArray. Больше нет ошибок :) Спасибо человеку: D (И как побочная заметка для путешественника, который спотыкается здесь с подобной проблемой, я создал временную базу NSMutableArray *, загрузил все данные там, а затем, что делает трюк вассалом. wordRelations = [NSArray arrayWithArray: tempArray] довольно грубая сила eh?;) –

Смежные вопросы