Я не знаком с этим синтаксическим анализатором JSON, но если он следует соглашениям Какао, objectWithString будет возвращать объект, выпущенный автоматически. Это означает, что он будет освобожден на следующей итерации через цикл запуска, если вы его не сохраните. Когда классы коллекции Какао освобождаются, они освобождают каждый содержащийся в них объект, поэтому категории также будут освобождены. Вот почему это работает сначала, но не позже в программе.
Причина, по которой он работает, делая его свойством, заключается в том, что созданный синтезированный сеттер сохраняет категории (при условии, что вы устанавливаете свое свойство с помощью параметра retain, что, я полагаю, вы сделали), поэтому оно не будет освобождено. Это правильное решение, хорошая работа. :) Вызов удержания по категориям также сработал бы.
Соглашение Какао состоит в том, что если имя метода содержит «alloc» или «copy» или начинается с «new», возвращаемый объект имеет счет сохранения 1, и вы несете ответственность за его освобождение. В противном случае возвращенный объект имеет нулевое количество сохранений (он был автоматически освобожден) и будет освобожден на следующей итерации в цикле выполнения, если только вы не сохраните его (в этом случае вы берете на себя ответственность за его последующее освобождение).
Я рекомендую прочитать это:
Руководство по программированию управления памятью для какао
Edit:
Причина, по которой он работал с использованием [[NSArray alloc] initWithObjects ...], заключается в том, что этот метод содержит «alloc», возвращенный массив не был автоматически выпущен, и поэтому он все еще появляется позже, когда вы обращаетесь к нему.