Есть ли способ принудительной проверки типов во время выполнения в Objective-C на какао? - PullRequest
1 голос
/ 11 января 2010

Привет, я нахожу способ обеспечить проверку типов во время выполнения или подобные вещи в Objective-C на какао.

Это мой пример кода. Я ожидал ошибку времени выполнения из-за неправильного присвоения переменной 'b'. Но это не так. Скомпилировано и выполнено без ошибок.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 NSArray* a = [NSArray arrayWithObject: @"TEST"]; 
 NSURL* b = [a objectAtIndex:0]; 

    NSLog(@"Is this URL? %i", [b isKindOfClass:NSURL.class]);
    [pool drain];
    return 0;
}

// Console log after program execution:
// 2010-01-11 10:25:02.948 Type Checking[98473:a0f] Is this URL? 0

Я удивлен тем, что здесь нет проверки типов во время выполнения. Поскольку я использовал все языки высокого уровня, такие как VB, C #, Java, ActionScript ... Я не знаю язык низкого уровня, такой как C, поэтому я не уверен, что это правильный путь ... Было действительно трудно понять, почему нет ошибки компиляции или времени выполнения. Но я понимаю это как естественное правило в реальном мире Си. Но более строгая проверка типов мне очень поможет. Даже только в сеансе отладки. Есть ли способ сделать это?

И если нет проверки типов во время выполнения, какую стратегию кодирования и отладки я должен использовать для неверно типизированных значений? И в чем заключается компромисс между проверкой типов во время выполнения или нет?

Ответы [ 3 ]

2 голосов
/ 11 января 2010

Ну, есть проверка типов во время выполнения, но это происходит немного позже. Я предполагаю, что вы ожидаете какого-то исключения, когда пытаетесь поместить экземпляр NSString в переменную NSURL *. Вместо этого вы получите исключение, когда попытаетесь вызвать любые специфичные для NSURL методы в вашем экземпляре NSString.

Например, если вы попробуете [b isFileURL], вы получите исключение типа "NSString не отвечает на селектор 'isFileURL'".

Также важно понять, почему в вашем примере нет проверки типов во время компиляции. В частности, отсутствие проверки типа во время компиляции является уникальным и важным свойством типа id, которое возвращает NSArray -objectAtIndex:.

1 голос
/ 11 января 2010

Objective-C имеет проверку типов во время компиляции для аргументов сообщений и возвращаемых типов, но он несколько слабее, чем во многих других языках. Одним из основных отличий является то, что классы коллекций, такие как NSArray и NSDictiomary, являются общими. Вы можете поместить любой тип объекта в NSArray - элементы не обязательно должны быть одного типа. Поэтому при добавлении или доступе к элементам проверки типов нет.

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

0 голосов
/ 11 января 2010

NSObject Framework часто поднимает шум, когда тип неправильный, но вы можете вручную проверить тип и выдать исключение:

if (![obj isKindOfClass:SomeObjectClass.class])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj xyz];

...

if (![obj conformsToProtocol:@protocol(SomeProtocol)])
  [NSException raise:@"BadTypeException"
    format:@"Bad type at line %d", (int)__LINE__];
[obj abc];

Редактировать : Удален предыдущий раздел, утверждающий, что вызовы несуществующих методов возвращают ноль или нули; как говорит Марк Бесси, исключение выдается (не возвращается ноль), если не ноль объект не реализует метод.

...