Несколько частей методов в Objective C - PullRequest
5 голосов
/ 23 августа 2011

Я изучаю Цель C и заметил эту причудливую причуду, читая о методах.

Как и Java и C ++, Obj.C может принимать несколько параметров, что хорошо, однако в нем говорится, что у объективных методов C может быть несколько имен, что, похоже, не соответствует мне.

Например:

-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

В приведенном выше примере есть два параметра, bombLocation (тип возвращаемого значения CGPoint) и поврежденный (тип возвращаемого значения BOOL), и вместе с именем метода, похоже, разделяется как shipatpoint: withDamage

Я не понимаю, что с этим ... Что это означает, когда говорится, что метод может иметь несколько имен? Это применимо только для методов, которые требуют нескольких параметров? С другой стороны, скажем, я хочу назвать свой метод одним именем, но предоставить ему несколько параметров, это возможно, или я должен предоставить ему несколько имен, каждое из которых соответствует параметру? Если да, то почему?

Спасибо, что запрыгнули с моим замешательством !!! :)

Ответы [ 5 ]

6 голосов
/ 23 августа 2011

Причина в том, чтобы облегчить понимание.

В вашем примере метод будет выглядеть примерно так в C ++:

 int shipsAtPointWithDamage (CGPoint bomb, BOOL damage)  //I don't really know C++ 

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

В Objective-C у вас есть

-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

Каждый параметр четко определен, первый - это точка корабля, второй - урон. Он читается как предложение , тогда как в C ++ (и почти во всех других языках) - нет.

Если вы хотите, чтобы метод имел несколько параметров в Obj-C, вы должны написать его следующим образом:

-(returnType)paraOne:(type*)name paraTwo:(type*)name

Это то, к чему нужно привыкнуть, все языки разные. Как только вы привыкнете к тому, как Objective-C работает, вы будете думать, что это просто фантастика.

РЕДАКТИРОВАТЬ: и как указал filipe, поскольку метод в качестве нескольких параметров не означает, что он имеет несколько имен, в приведенном выше примере имя метода будет paraOne:paraTwo, НЕ paraOne:

3 голосов
/ 23 августа 2011

Objective-C использует систему передачи сообщений на основе селекторов.Это не совсем то же самое, что вызов метода.Когда вы видите такой код:

[world shipsAtPoint:point withDamage:YES];

, который преобразуется в следующий вызов C (в наиболее распространенном случае):

objc_msgSend(world, @selector(shipsAtPoint:withDamage:), point, YES);

Конструкция @selector() возвращает уникальный идентификатор,Точный формат этого идентификатора является внутренней деталью реализации.

objc_msgSend включает довольно много логики в несколько десятков байтов ассемблера.Но в простейшем случае он ищет класс для world, просматривает таблицу селекторов, пока не находит тот, который соответствует shipsAtPoint:withDamage:, а затем захватывает указатель на функцию в этом слоте.Затем он переходит к указателю на эту функцию, оставляя остальные параметры в покое (в регистрах или в стеке, в зависимости от процессора).Функция в этом месте - ваш метод, и она знает порядок и типы своих параметров на основе вашего объявления.

Для вас важно то, что селектор - shipsAtPoint:withDamage:.Как правило, это единственное имя метода.Там нет "несколько имен", как вы предлагаете.(Обычно .... среда выполнения Objective-C очень мощная, и можно указывать несколько селекторов на одну и ту же реализацию.)

Как указывает Джо, селектор может иметь форму foo::.Это будет представлять метод, который принимает два параметра и будет вызываться как [world foo:point :YES].Вы никогда не должны делать это.Это невероятно сложно читать.Но это законно.

2 голосов
/ 23 августа 2011

Я думаю, что вы в замешательстве. Метод не может иметь несколько имен, но аргумент может быть назван по-другому в заголовке, чем в реализации.

Имя этого метода shipsAtPoint:withDamage:. Это также известно как selector.

Этот метод возвращает экземпляр NSArray и принимает CGPoint в качестве первого аргумента и BOOL в качестве второго аргумента.

Однако имена аргументов могут отличаться. Это полностью верно:

// .h file
-(NSArray *)shipsAtPoint:(CGPoint)bombLocation withDamage:(BOOL)damaged;

// .m file
-(NSArray *)shipsAtPoint:(CGPoint)loc withDamage:(BOOL)dmg {
  // ...
}

Наконец, ObjC - это, в основном, хороший синтаксический сахар. Вы должны знать, что любой вызов метода действительно сводится к некоторому C, который выглядит примерно так:

objc_msgSend(receiverObj, @selector(shipsAtPoint:withDamage:), point, damage);

Итак, в конце дня у вас есть получатель, селектор и ваши аргументы. Но синтаксис ObjC намного лучше, чем этот.

2 голосов
/ 23 августа 2011

Здесь - лучшее объяснение, которое я когда-либо видел.Он включает в себя сравнения с C ++ / C, а также много другой полезной информации.

0 голосов
/ 23 августа 2011

Можно предоставить метод без помеченных параметров, но это явно не рекомендуется.

-(void)badmethod:(id)obj1:(id)obj2:(id)obj3
{

}

//...
//Usage
[self badmethod:nil :nil :nil];

SEL sel = @selector(badmethod:::);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...