Чтобы представить большую картину, я собираюсь объяснить как динамическое, так и лексическое связывание.
this
относится к объекту, . Это регулярно читаемое предложение на SO. Но это все еще только фраза, довольно абстрактная. Есть ли соответствующий шаблон кода для этого предложения?
Да, есть:
const o = {
m() { console.log(this) }
}
// the important patterns: applying methods
o.m(); // logs o
o["m"](); // logs o
m
- это метод, потому что он полагается на this
. o.m()
или o["m"]()
означает m
применяется к o
. Эти шаблоны - это перевод Javascript на нашу знаменитую фразу.
Существует еще один важный шаблон кода, на который вы должны обратить внимание:
"use strict";
const o = {
m() { console.log(this) }
}
// m is passed to f as a callback
function f(m) { m() }
// another important pattern: passing methods
f(o.m); // logs undefined
f(o["m"]); // logs undefined
Он очень похож на предыдущий шаблон, только скобки отсутствуют. Но последствия значительны: когда вы передаете m
функции f
, вы вытаскиваете m
своего объекта / контекста o
.
Функции стрелок не имеют собственных this
/ super
/ arguments
. Они наследуют их от родительской лексической области:
const toString = Object.prototype.toString;
const o = {
foo: () => console.log("window", toString.call(this)),
bar() {
const baz = () => console.log("o", toString.call(this));
baz();
}
}
o.foo() // logs window [object Window]
o.bar() // logs o [object Object]
Помимо глобальной области (Window
в браузерах) только функции способны сформировать область видимости в блоках Javascript (и {}
в ES2015). Когда вызывается функция стрелки o.foo
, нет никакой окружающей функции, из которой baz
может наследовать ее this
. Следовательно, он фиксирует привязку this
глобальной области действия, привязанную к объекту Window
.
Когда baz
вызывается o.bar
, функция стрелки окружена o.bar
( o.bar
формирует родительскую лексическую область) и может наследовать привязку o.bar
this
. o.bar
был вызван на o
, и поэтому его this
привязан к o
.
Если Вы захотите использовать NSArray, то необходимо будет втиснуть структуры. Можно использовать класс NSValue для кодирования их.
Что-то вроде этого для кодирования:
struct foo {
int bar;
};
struct foo foobar;
foobar.bar = 3;
NSValue *boxedFoobar = [NSValue valueWithBytes:&foobar objCType:@encode(struct foo)];
И затем вернуть его:
struct foo newFoobar;
if (strcmp([boxedFoobar objCType], @encode(struct foo)) == 0)
[boxedFoobar getValue:&newFoobar];
Или динамично выделение:
struct foo {
int bar;
};
int main (int argc, const char * argv[]) {
struct foo *foobar = malloc(sizeof(struct foo) * 3);
foobar[0].bar = 7; // or foobar->bar = 7;
free(foobar);
}
Это должна быть структура? Обычно лучше сделать это объектом, если Вы можете. Затем можно использовать вещи как KVC и Привязка с ним.
Если Вы хорошо с регулярным старым массивом C:
struct foo{
int bar;
};
int main (int argc, const char * argv[]) {
struct foo foobar[3];
foobar[0].bar = 7;
}
, Если Вы хотите NSArray, Вам будет нужен интерфейсный объект. Большинство примитивов использует NSNumber, но это не могло бы быть применимо к Вашей структуре. Обертку не было бы очень трудно записать, хотя такие поражения цель использовать структуру!
Редактирование: Это - что-то, что я не сделал, но просто думал. Если Вы думаете об этом, NSDictionary является в основном структурой для объектов. Ваши ключи могут быть названиями компонентов структуры как NSStrings, и Ваши значения могут иметь соответствующий тип данных, перенесенный в применимую обертку Какао. Затем просто помещенный эти словари в NSArray.
я предполагаю, что суть - то, что у Вас есть много опций. На вашем месте я сделал бы некоторое экспериментирование и видел бы что работы лучше всего.