Ответ 1
Это должно работать:
@interface MyClass
{
int _doubleDigits[10];
}
@property(readonly) int *doubleDigits;
@end
@implementation MyClass
- (int *)doubleDigits
{
return _doubleDigits;
}
@end
У меня проблемы с созданием свойства массива целых чисел в Objective-C. Я не уверен, что это вообще возможно сделать в Obj-C, поэтому я надеюсь, что кто-то может помочь мне узнать, как это сделать правильно или предложить альтернативное решение.
myclass.h
@interface myClass : NSObject {
@private int doubleDigits[10];
}
@property int doubleDigits;
@end
myclass.m
@implementation myClass
@synthesize doubleDigits;
-(id) init {
self = [super init];
int doubleDigits[10] = {1,2,3,4,5,6,7,8,9,10};
return self;
}
@end
При сборке и запуске я получаю следующую ошибку:
ошибка: тип свойства 'doubleDigits' не соответствует типу ивара 'doubleDigits'
Это должно работать:
@interface MyClass
{
int _doubleDigits[10];
}
@property(readonly) int *doubleDigits;
@end
@implementation MyClass
- (int *)doubleDigits
{
return _doubleDigits;
}
@end
C массивы не являются одним из поддерживаемых типов данных для свойств. См. "Язык программирования Objective-C" в документации Xcode на странице "Объявленные свойства":
Поддерживаемые типы
Вы можете объявить свойство для любого Objective-C класс, Core Foundation тип данных или "простые старые данные" (POD) type (см. С++ Language Note: POD Типы). Ограничения на использование Core Типы фондов, однако, см. "Core Фонд".
POD не включает массивы C. Видеть http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
Если вам нужен массив, вы должны использовать NSArray или NSData.
Обходные пути, как я вижу, похожи на использование (void *), чтобы обойти проверку типов. Вы можете это сделать, но это делает ваш код менее ремонтопригодным.
Как сказал Люциус, невозможно иметь свойство массива C. Использование NSArray
- путь. Массив сохраняет только объекты, поэтому вам нужно будет использовать NSNumber
для хранения ваших int. С новым синтаксисом literal инициализация очень проста и прямолинейна:
NSArray *doubleDigits = @[ @1, @2, @3, @4, @5, @6, @7, @8, @9, @10 ];
Или:
NSMutableArray *doubleDigits = [NSMutableArray array];
for (int n = 1; n <= 10; n++)
[doubleDigits addObject:@(n)];
Для получения дополнительной информации: Ссылка на NSArray Class, Ссылка на NSNumber Class, Литературный синтаксис
Я просто размышляю:
Я думаю, что переменная, определенная в ivars, выделяет пространство прямо в объекте. Это предотвращает создание аксессуаров, потому что вы не можете передать массив по значению функции, но только через указатель. Поэтому вам нужно использовать указатель в ivars:
int *doubleDigits;
И затем выделите пространство для него в init-методе:
@synthesize doubleDigits;
- (id)init {
if (self = [super init]) {
doubleDigits = malloc(sizeof(int) * 10);
/*
* This works, but is dangerous (forbidden) because bufferDoubleDigits
* gets deleted at the end of -(id)init because it on the stack:
* int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
* [self setDoubleDigits:bufferDoubleDigits];
*
* If you want to be on the safe side use memcpy() (needs #include <string.h>)
* doubleDigits = malloc(sizeof(int) * 10);
* int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
* memcpy(doubleDigits, bufferDoubleDigits, sizeof(int) * 10);
*/
}
return self;
}
- (void)dealloc {
free(doubleDigits);
[super dealloc];
}
В этом случае интерфейс выглядит следующим образом:
@interface MyClass : NSObject {
int *doubleDigits;
}
@property int *doubleDigits;
Edit:
Я действительно не уверен, что это разрешено делать, эти значения действительно находятся в стеке или они хранятся где-то в другом месте? Вероятно, они хранятся в стеке и поэтому небезопасны для использования в этом контексте. (См. Вопрос в списках инициализаций)
int bufferDoubleDigits[] = {1,2,3,4,5,6,7,8,9,10};
[self setDoubleDigits:bufferDoubleDigits];
Это работает
@interface RGBComponents : NSObject {
float components[8];
}
@property(readonly) float * components;
- (float *) components {
return components;
}
Вы можете поместить это в свой .h файл для своего класса и определить его как свойство в XCode 7:
@property int (*stuffILike) [10];
Я нашел все предыдущие ответы слишком сложными. Мне нужно было сохранить массив некоторых int как свойство и найти требование ObjC использовать NSArray для ненужного усложнения моего программного обеспечения.
Итак, я использовал это:
typedef struct my10ints {
int arr[10];
} my10ints;
@interface myClasss : NSObject
@property my10ints doubleDigits;
@end
Это компилируется с использованием Xcode 6.2.
Мое намерение было использовать его следующим образом:
myClass obj;
obj.doubleDigits.arr[0] = 4;
ОДНАКО, это не работает. Это то, что он производит:
int i = 4;
myClass obj;
obj.doubleDigits.arr[0] = i;
i = obj.doubleDigits.arr[0];
// i is now 0 !!!
Единственный способ правильно использовать это:
int i = 4;
myClass obj;
my10ints ints;
ints = obj.doubleDigits;
ints.arr[0] = i;
obj.doubleDigits = ints;
i = obj.doubleDigits.arr[0];
// i is now 4
и так, полностью поражает мою точку (избегая осложнений использования NSArray).