Не удается получить значение с размером 16. Тип, закодированный как {?={CGPoint=dd}d}, как ожидается, составит 24 байта

#ios #objective-c #nsvalue

Вопрос:

Эта ошибка появляется при попытке получить CGPoint из NSValue:

«Не удается получить значение с размером 16. Тип, закодированный как {?={CGPoint=dd}d}, как ожидается, составит 24 байта»

 for (NSValue *p in array) {
      CGPoint pointValue = p.CGPointValue; //Here appears this error
}

for (NSValue *p in array) {
      CGPoint pointValue = [p CGPointValue]; //Here appears this error too
}
 

Значение NSValue создается из библиотеки и не может получить к нему доступ.

Редактировать 1 p.objCType Результаты печати: {CGPoint=dd}

Редактировать 2 Результат печати массива:

     2021-09-09 16:04:04.251526 0200 App[4964:674948] (
        "{length = 24, bytes = 0xa3b27988de206940eb42b35cc9586740000000000000f03f}",
        "{length = 24, bytes = 0x33b2fe8e136f6840ace8651ab5b967409dc9d7ee7b0bef3f}",
        "{length = 24, bytes = 0xc154b1089cdd6740ace8651ab5b96740b28e3f23264dea3f}",
        "{length = 24, bytes = 0x580edb282aeb6640d62444f11779674016af93916f39e63f}",
        "{length = 24, bytes = 0xf581a96211b865401f0e49e9040867404ded927b8a12e33f}",
        "{length = 24, bytes = 0x1324e1e2ce74644087a474027c66664034f3481fe7b4e13f}",
        "{length = 24, bytes = 0x3523ebef38116340ef3aa01bf3c46540778fc387b583e03f}",
        "{length = 24, bytes = 0x506850e349ee6140777ef255f4f26440e3d77dc1a4b2e13f}",
        "{length = 24, bytes = 0xea7e4c9084db6040ffc14490f52064405e2015fe2ed3e23f}",
        "{length = 24, bytes = 0xfe131ad478f25f40a6b2bdeb801e63401999aea8afcae13f}",
        "{length = 24, bytes = 0x149fdaad30105f4042147f91332c62404e8f96066287e53f}",
        "{length = 24, bytes = 0x1db6515436af5e40ca57d1cb345a6140679349620e80e73f}",
        "{length = 24, bytes = 0x1db6515436af5e40529b230636886040f83000f8e0c2e73f}",
        "{length = 24, bytes = 0x1db6515436af5e409e9f7c15bd8c5f40153010013271e83f}",
        "{length = 24, bytes = 0x0a8863072b715f406fccd347ab495e40869a27450e63e83f}",
        "{length = 24, bytes = 0x71675af0b38a604054179ae54ae65c40a7e25a959d81e53f}",
        "{length = 24, bytes = 0x5cdc9916fc6c6140fb071341d6e35b4069a857606cb8e53f}",
        "{length = 24, bytes = 0xc52270f66d5f62408dda1c31b0015b40d144c5cd8e6ee53f}",
        "{length = 24, bytes = 0xaadd0a035d826340cc346a73c4a05a40b88edb022dbbe43f}",
        "{length = 24, bytes = 0x0d6a3cc975b56440f670484a27605a40ef474c247756e33f}",
        "{length = 24, bytes = 0x6d999b02e2086640f670484a27605a40a01777914c97e23f}",
        "{length = 24, bytes = 0x493dbf68cb8c6740f670484a27605a40b2b27e1fcb90e03f}",
        "{length = 24, bytes = 0x2a9b87e80dd06840cc346a73c4a05a402a0dc7148d2ae33f}",
        "{length = 24, bytes = 0x0cf94f6850136a404f80cfee9b625b4077e1eade1208e33f}",
        "{length = 24, bytes = 0xf0b3ea743f366b40bcadc5fec1445c40538bb556a938e33f}",
        "{length = 24, bytes = 0xdb282a9b87186c403ff92a7a99065d40e0d373bbad4ee63f}",
        "{length = 24, bytes = 0xc9fa3b4e7cda6c40d762ff6022a85d4049ccc22b4fc7e73f}",
        "{length = 24, bytes = 0x3b5889d4f36b6d403072860597aa5e40c7cefa969a66e83f}",
        "{length = 24, bytes = 0xb7cc4d01719c6d40f11739c3820b5f40ac55403eec59ed3f}"
    )
 

Правка 3
Обратите внимание, что получение значения таким образом:

 CGPoint pointValue = CGPointMake(0, 0);
[p getValue:amp;pointValue];
 

Работает в режиме отладки, но выходит из строя в выпуске.

Комментарии:

1. Скорее всего, на самом NSValue деле он не содержит а CGPoint . Вы пробовали печатать p.objcType ?

2. Вопрос отредактирован: p.Тип объекта печать «{CGPoint=dd}» @Sulthan Спасибо вам

3. Одна из вещей в вашем списке не является контрольной точкой. Может быть, это похоже на квартал? Как вы создали этот список NSValues? (Скорее всего , если вы NSLog(@"%@", array) , вы увидите тот, который не похож на другие.)

4. Вопрос edit2: печать массива выводит заданный результат. @RobNapier

5. Я имел в виду, как вы создаете NSValues, а не как вы их читаете. Код, который вы показали здесь, не создает значение NSValue. Это не то , что вы получили бы, если бы создали эти объекты NSValue с помощью valueWithCGPoint: , поэтому я ожидаю, что вы делаете это каким-то другим неверным способом. Обратите внимание, что -getValue: это устарело с iOS 11.

Ответ №1:

 struct { // just here for reference
   CGFloat x;
   CGFloat y;
} CGPoint; 

struct {
   CGPoint p;
   double d;
} AssumedEntryType;

typedef AssumedEntryType SomeEntry;
 

d проживание на двоих.
Глядя на вашу отладочную печать, кажется, что это 3 значения в структуре. Таким образом, эти числа могут представлять любой тип данных, который помещается в 8 байтах каждый (8*3=24).

Внутренне экземпляры NSValue состоят из большого двоичного объекта байтов в паре со строкой C, описывающей имя и структуру байтов.

Если {?={CGPoint=dd}d} вы описываете строку C NSValue, то вы должны иметь возможность выполнить следующее декодирование в качестве расширения NSValue

 -(SomeEntry)someEntryValue 
{
    SomeEntry entry;
 
    [self getValue:amp;entry];
 
    return entry;
}
 

И да, значения NSValues все еще можно собирать в NSArray.
Просто следуйте тому, что вам сказано в описании структуры C.

Ps: не протестированный код.. Некоторые подсказки взяты из этого результата поиска Google или читайте больше на NSHipster

Правка: как отметил Роб..
существуют различные списки для кодировок objCType и спецификаторов StringFormat

А вот документация по NSValue

Комментарии:

1. В обозначении d objCType это двойной, а не int. Я думаю, что вы путаете строки формата NSString /printf для objctype. ( s тоже нет char* , * есть.)

2. Даже лучше. Потому что все еще 8 байт, не стесняйтесь редактировать..