объективный-c “видоизменяющийся метод отправляется в неизменную объектную” ошибку

Замещающий знак используется для разрезания более многомерных структур данных.

Это разработано, чтобы означать в этой точке, вставить как много полных частей (:) для расширения многомерной части до всех размеров .

Пример :

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

Теперь, у Вас есть 4-мерная матрица порядка 2x2x2x2. Для выбора всех первых элементов в 4-м размере можно использовать нотацию

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

замещающего знака, которая эквивалентна

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

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

7
задан John Calsbeek 3 August 2009 в 23:38
поделиться

2 ответа

Sending the copy message to an NSMutableArray -- as in the following statement in init -- returns an immutable copy.

self.tableList = [localList copy];

Cocoa documentation uses the word immutable to refer to read-only, can't-be-changed-after-initialization objects. Hence the subsequenct call to addObject: fails with an error message.

Note how the assignment statement above doesn't trigger any compiler warning. copy returns an id, which fits comfortably -- as far as the compiler is concerned -- in the NSMutableArray* tableList. There's no runtime error here either, as no messages get passed around; an NSArray pointer is just placed in an NSMutableArray pointer variable.

To obtain a mutable copy, use mutableCopy instead.

Note that both copy and mutableCopy create a new array and copy the content of the original to it. A change in the copy will not be reflected in the original. If you just need another reference to the original array, use retain instead.

You can find more detail in the discussion section of the copyWithZone reference and in the NSMutableCopying protocol reference.

27
ответ дан 6 December 2019 в 05:43
поделиться

В основном вы сталкиваетесь с правилами управления памятью Какао ( в частности, с этими деталями ). Если есть объект с неизменной версией и изменяемой версией, то отправка -copy объекту вернет неизменяемый объект.

Давайте пройдемся по соответствующей части.

NSMutableArray *localList = [[NSMutableArray alloc] init];

Это создает новый пустой изменяемый массив, которым вы владеете. Хорошо.

self.tableList = [localList copy];

Это создает неизменяемую копию пустого массива. Кроме того, вы являетесь владельцем этой только что созданной копии. Это два объекта, которыми вы владеете в данный момент.

Это также назначает ваш скопированный объект свойству tableList . Давайте посмотрим на объявление свойства:

@property (nonatomic, copy, readwrite) NSMutableArray *tableList;

Это свойство объявляется с атрибутом copy , поэтому всякий раз, когда ему присваивается новое значение, ему отправляется другой метод -copy . Однако эта третья копия не принадлежит вам - она ​​принадлежит объекту.

[localList release];

Это освобождает исходный пустой изменяемый массив. Хорошо, но есть еще тот, который вы сделали во второй строке, плавающий, неизданный. Это утечка памяти.

Если вам действительно нужна изменяемая копия чего-либо, вам нужен метод -mutableCopy . (Документация для этих методов находится в разделах NSCopying и NSMutableCopying .) Однако вы никогда не получите изменяемую версию чего-либо в свойстве с копией , так как он отправит -copy тому, что ему назначено. Свойство должно использовать атрибут сохранить вместо атрибута copy ,

5
ответ дан 6 December 2019 в 05:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: