Правильный способ использования массивов в MonoMac - PullRequest
6 голосов
/ 06 ноября 2010

Я только начал работать над проектом в MonoMac, который пока довольно крутой. Но есть некоторые вещи, в которых я не уверен. Например: как вы используете массивы? Вот что я узнал: когда я получаю NSArray от метода, который я вызываю, и пытаюсь получить один из пользовательских объектов в этом массиве, я продолжаю получать что-то вроде "cannot convert type System.IntPtr to MyType".

NSArray groupArray = (NSArray)groupDictionary.ObjectForKey(key);
MyType myObject = (MyType)groupArray.ValueAt(0);

Это для массивов, которые я возвращаю. Но что, если я хочу создать массив самостоятельно? Реализация NSArray не позволяет мне создавать его экземпляры. Так что, если я правильно понял веб-сайт MonoMac , я должен использовать обычный массив, подобный этому

int[] intArray = int[10];

соответственно строго типизированный массив, который я не знаю, как использовать его в C #.

Так, как сюда идти?

Спасибо
-f

1 Ответ

11 голосов
/ 06 ноября 2010

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

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

Обычно вы делаете это:

YourType [] stronglyTyped = NSArray.ArrayFromHandle<YourType> (arrayIntPtrHandle);

Обратите внимание, что NSArray может хранить только NSObjects, поэтому для "YourType" необходимобыть объектом, полученным из NSObject.

Теперь, если вы все еще хотите использовать NSArray, вам нужно помнить, что ValueAt возвращает базовый дескриптор объекта (IntPtr), чтобы использовать его с C #, вам нужно преобразовать его в NSObject.Вы делаете это с помощью метода Runtime.GetNSObject, вы можете привести результат к наиболее производному типу:

YourType x = (YourType) Runtime.GetNSObject (NSArray.ValueAt (0));

При этом, если вы используете инструменты привязки API для доступа к Objective-C API,Вы не связываете вещи правильно.У вашего контрактного API вместо NSArray должна быть строго типизированная версия, поэтому:

 [Export ("getElements")]
 NSArray GetElements ();

Должно стать:

 [Export ("getElements")]
 YourType [] GetElements ();
...