Как вы можете выделить класс в objective-c из объекта NSString?

У меня есть опыт работы с PHP, но я начинаю изучать Objective-C, чтобы разрабатывать приложения для iPhone. Пока все идет хорошо, но у меня есть вопрос, на который я еще не смог найти и ответить после того, как погуглил и поработал на нескольких различных форумах.

Мое приложение должно создать несколько представлений, каждое со своей собственной строкой заголовка uinque. Для этого мой код для каждого представления выглядит примерно так:

    xViewController = [ [ XViewController alloc ] init ];
    xNavController = [ [ UINavigationController alloc ]
        initWithRootViewController: xViewController
    ];
    xNavController.tabBarItem = [ [ UITabBarItem alloc ]
        initWithTitle: @"My Info"
        image: [ UIImage imageNamed: @"my_info.png" ]
        tag: 3
    ];  

Это работает, но я бы хотел создать метод, который будет возвращать навигационный контроллер при отправке строки в виде сообщения, поэтому мне не нужно делать все это для каждого представления. Проблема, с которой я столкнулся, заключается в том, что первая строка должна выделить объект на основе имени класса, переданного ему в виде строки (т.е. XViewController необходимо взять из строки, переданной методу), но я не знаю, как это сделать. рассматривать строку как имя класса. Я знаю, что это возможно, потому что UIApplicationMain () может использовать строку для вызова класса делегата приложения. Как мне это сделать?

Прошу прощения, если что-то из этого не имеет смысла, я все еще нахожусь на ранних этапах изучения нового языка!


person JoBu1324    schedule 22.06.2009    source источник
comment
Вы можете сделать это (как показывают ответы ниже), но я не понимаю, как это может сделать ваш код меньше, проще или менее подверженным ошибкам?   -  person Stephen Darlington    schedule 22.06.2009
comment
Почему вы должны передавать строку в качестве параметра? Почему вы не можете передать класс в качестве параметра?   -  person Chris Suter    schedule 22.06.2009
comment
Стивен, он сделает все, о чем вы просите, потому что мне не придется повторять приведенный выше код для каждого создаваемого представления - я могу просто вызвать метод, который делает это каждый раз правильно, с помощью одной строчки кода. Крис, я не знал, что могу просто передать класс в качестве параметра, если честно, но я думаю, что это все равно работает лучше, потому что я хочу использовать строку для имени класса, метода initWithTitle и изображения название.   -  person JoBu1324    schedule 22.06.2009


Ответы (4)


Помимо использования среды выполнения, вы можете сделать это, просто используя методы Cocoa-touch:

NSString* theClassName = /* assume this exists */
Class theClass = NSClassFromString(theClassName);
NSObject* myObject = [[theClass performSelector:@selector(alloc)] init];
// do something with the new object instance
person Jason Coco    schedule 22.06.2009
comment
Именно то, что я ищу. Спасибо, Джейсон! - person JoBu1324; 22.06.2009
comment
Вам не нужен performSelector :, вы можете просто написать [[theClass alloc] init]. - person Jon Hess; 24.07.2009

Если у вас есть несколько TableViewCell, загруженных из NIB, код для загрузки отдельных NIB станет некрасивым, если вы не сделаете что-то с динамической загрузкой.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // header
    if (indexPath.row == 0) {
        cellHeader *cell = (cellHeader *)[self loadCell:identHeader];
        return cell;

    // load more
    } else if (indexPath.row == lastRow) {
        loadMore *cell = (loadMore *)[self loadCell:identLoadMore];
        return cell;
    }

    // default
    cellDefault *cell = (cellDefault *)[self loadCell:identDefault];
    return cell;
}

- (id)loadCell:(NSString *)className {
    id cell = [tweetsView dequeueReusableCellWithIdentifier:className];

    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:className owner:nil options:nil];

        for (id currentObject in topLevelObjects) {
            if ([currentObject isKindOfClass:[UITableViewCell class]]) {
                cell = currentObject;
                break;
            }
        }
    }

    return cell;
}
person Community    schedule 23.07.2009

Используйте Objective-C 2.0 Справочник по среде выполнения

person J-16 SDiZ    schedule 22.06.2009

Если я правильно понимаю вашу проблему, вам не нужны динамические классы для этой работы. Почему бы не создать для каждого класса контроллера представления свой уникальный метод title и image, который просто возвращает уникальный заголовок и изображение для этого контроллера представления. Затем создайте суперкласс для классов контроллера представления с помощью фиктивных методов title и image.

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

- (UINavigationController *)getNavController:(XGenericViewController *)viewController
{
        UINavigationController  *xNavController = [ [ UINavigationController alloc ]
            initWithRootViewController: viewController
        ];
        xNavController.tabBarItem = [ [ UITabBarItem alloc ]
            initWithTitle: [viewController title]
            image: [viewController image]
            tag: 3
        ];

    return [xNavController autorelease];
}
person diederikh    schedule 22.06.2009