Показаны сообщения с ярлыком xcode. Показать все сообщения
Показаны сообщения с ярлыком xcode. Показать все сообщения

пятница, 20 сентября 2013 г.

Как быстро выяснить, кто виноват в том, что обычный контрол (UIView, UIImageView и прочего стандартного класса) уехал куда-то в сторону

Просто быстро на время создайте подкласс (например для UIImageView создайте его дочерний класс UIImageView2). Для этого даже не создавайте отдельные исходники, добавьте interface часть в заговолочный файл в класс того контроллера, где возникает непонятный баг. В исполняемый файл (m) добавьте implementation вашего UIImageView2 класса всего лишь с одним методом setFrame (этим методом вы переопределите стандартный setFrame-метод). Вот как это сделал я

@implementation UIImageView2

- (void)setFrame:(CGRect)frame
{
    NSLog(@"++++++ frame.origin.x = %f", frame.origin.x);
    [super setFrame:frame]; // сюда поставьте брекпоинт, чтобы выяснить какая такая "сволочь" портит фрейм вашего объекта на окне :)
}

@end

вторник, 2 июля 2013 г.

Инструмент Automation (автоматическое тестирование iOS-приложений) - некоторые способы обойти траблы

Инструмент Automation позволяет автоматически тестировать iOS приложения, используя для написания тестовых скриптов JavaScript.

Вероятно, в Apple решили, что заботиться об удобстве работы программистов не настолько остро актуально в отличие от заботы о массовом пользователе... В общем Automation имеет ряд неприятных багов.

1 баг:
Кнопка нажимается с точки зрения Automation, но вы своими глазами видите на экране, что ничего не произошло. В таком случае я выхожу из положения так: я вставляю в скрипте цикл (обычно хватает 2-3 итераций), с помощью которого выясняю встроенными в Automation JavaScript-функциями произошло ли то, что должно произойти после нажатия (например, появилось ли окно, что можно проверить через myView.isVisible() && myView.isValid() условие)

2 баг:
Кнопка, контрол или что-нибудь ещё вообще никак не реагирует на нажатие, если это нажатие является первым нажатием по только что открытому окну. Спасает меня вот что: я с помощью скрипта "провожу пальцем" по тому месту (обычно это середина верхнего бара), где можно водить и это ни к чему не приведёт. После этого окно "оживает" и дальше уже можно нажимать на кнопку.

вторник, 22 января 2013 г.

Как прицеплять в Xcode-проект статические либы отдельно для Debug и Release

Это касается только Xcode 4 и более поздних версий:

ПЕРВЫЙ ТРУДОЁМКИЙ СПОСОБ: прицепить либы к дереву проекта намертво (вероятно можно и мышкой добавить нужные либы из Finder-папки перетаскивая их прямо в дерево проекта), но я делал это выходя в свойства проекта, потом переключался на вкладку Target, выбирал там Build Phases -> Link Binary With Libraries.

Этот первый способ плох тем, что Xcode порой глючит, и не в состоянии отличить дебаг-либу от релизной и может прицеплять дебаг-либу при релизной сборке приложения. Поэтому мне пришлось написать shell-скрипты, которые прятали в Temp-папки те либы, которые мне мешали и shell-скрипты для возвращения этих либ на прежние места. То есть перед Release-сборкой приложения все дебаг-либы можно аккуратно убрать одним запуском скрипта - при этом эти либы окрасятся в тревожный красный цвет в дереве проекта, но пусть это вас не пугает - приложение будет исправно собираться с оставшимися релизными либами.

НОВЫЙ ХОРОШИЙ СПОСОБ (пока плохо мной оттестирован): не добавлять либы первым способом в дерево проекта. Добавьте пути к нужным либам (включая имена файлов этих собранных либ) в настройках проекта и настройках таргета  -> Build Settings -> Linking -> Other Linker Flags (в подраздел Debug добавьте пути к дебаг-либам, в подраздел Release - к релиз-либам). Кроме того, вы можете в Debug/Release подразделы добавить вложенные подразделы для разных таргетов (для симуляторов и девайсов) - для этого найдите + кнопку справа внизу "Add Build Settings", нажмите на неё и выберите "Add Conditional Settings" (укажите пути для симуляторных и девайсовских дебаг/релиз либ).

суббота, 4 февраля 2012 г.

О важности IBOutlet прикрепления объектов к объекту-хозяину

Очень важно, если вы решили часть рутинных операций возложить на такой удобный инструмент как Interface Builder не забывать об одном правиле. Каждый объект, который создаётся не динамически в коде (например smthObject = [[SmthClass alloc] initWith... ]), а создан с помощью Interface Builder, каждый такой объект должен иметь своего хозяина (разве что главный делегат приложения гарантированно работает по умолчанию).

То есть любой ваш объект (созданный с помощью Interface Builder) должен принадлежать кому-нибудь как IBOutlet-переменная. Я убеждался в этом уже много раз на практике. Иначе происходят падения программы при попытке заставить этот объект что-либо сделать, из-за того, что у этого объекта (если он не принадлежит никому как IBOutlet-переменная) например вызывается метод, а объект вроде не существует (раз ни к кому не принадлежит). Может быть гуру-программисты дадут более точное объяснение этому явлению...

среда, 2 ноября 2011 г.

Как собирать проекты с гигантскими функциями

Случается так, что гигантские функции (в несколько тысяч строк кода) не позволяют собрать проект. Если нет ошибок компиляции, но есть непонятная ошибка линковки, то попробуйте в свойствах Xcode-проекта убрать галочку с пункта GCC 4.2 Code Generation -> Compile for Thumb. Мне это помогло (нашёл совет где-то в англоязычных сайтах).

понедельник, 31 октября 2011 г.

Мои скрипты для работы в Xcode

Вот какие скрипты я использую для работы в Xcode (на них можно назначать сочетания клавиш). Для добавления скриптов и назначения им сочетаний клавиш найдите в полосе меню (у меня Xcode 3) пункт, напоминающий свиток, а в нём субменю Edit user scripts...

В ОСНОВНОМ ЭТО СКРИПТЫ ДЛЯ ДОБАВЛЕНИЯ ЧАСТО ИСПОЛЬЗУЕМЫХ СТРОК (без горячих сочетаний клавиш теряется их неоценимая помощь в работе):

1) Добавление NSLocalizedString(@"", @"")
#!/bin/sh
echo "NSLocalizedString(@\"\", @\"\")"

2) Добавление // property
#!/bin/sh
echo "// property"

3) и так далее до пункта 11)
#!/bin/sh
echo "@property (nonatomic, retain) IBOutlet "

4)
#!/bin/sh
echo "//----------------------------------------------------------"

5)
#!/bin/sh
echo "////////////////////////////////////////////////////////////"

6)
#!/bin/sh
echo "NSLog(@\"\");"

7)
#!/bin/sh
echo "NSLog(@\"%s function %s \", __FILE__, __FUNCTION__);"

8)
#!/bin/sh
echo "NSLog(@\"%s line %d \", __FILE__, __LINE__);"

9)
#!/bin/sh
echo "using namespace "

10)
#!/bin/sh
echo "@synthesize "

11) Вставляю свои инициалы, дату и время (чтобы не забыть удалить после экспериментов)
#!/bin/sh
echo "//MD:$(date +%Y%m%d-%H:%M)"

12)
#!/bin/sh
echo "////////////////////////////////////////////////////////////"
echo "#pragma mark -"
echo "#pragma mark methods"
echo "////////////////////////////////////////////////////////////"

13) Сначала выделяете нужный текст (например имя функции). После выполнения этого скрипта у вас получится в коде вывод в отладочную консоль выделенного текста.
#!/bin/sh
echo "NSLog(@\"%%%{PBXSelectedText}%%%\");";

воскресенье, 18 сентября 2011 г.

Регулярные выражения для поиска в исходниках Xcode-проекта

[^//][^ ]NSLog - это регулярное выражение для поиска всех незакомментированных NSLog (лично я люблю выводить в лог всяческие значения и прочую лабуду, которая помогает мне понять, что вообще происходит в программе, не всегда это можно сделать только с одними брекпоинтами).

[^a-zA-Z_]id[^a-zA-Z_] - это регулярное выражение для поиска всех id, где справа и слева нет букв и нет знаков подчёркивания (может пригодиться, если вам нужно заменить тысячи локальных переменных или мемберов в тех коллективных исходниках, которые писали те плюсовые программисты, которые не знали или забыли (а у вас не хватает наглости их упрекать за повторяющуюся забывчивость), что в Obj-С id является именем типа (псевдоним типа NSObject*). Внимание! Квадратные скобки дают нам по одному символу слева и справа от id, которые не являются буквами и знаком подчёркивания. То есть поиск нам выдаст в числе прочих и всё 4 буквенные строки, где в центре каждой строки мы имеем id.

Поэтому, если вам нужно заменять в коллективных Си++ исходниках id на _id (ведь id является типом данных в Objective C, а ваши cpp файлы наверняка будут настроены в дереве проекта как cpp.objcpp файлы), то лучше сделайте так:

Вставьте в поле Find:
([^a-zA-Z_])id([^a-zA-Z_])
Вставьте в поле Replace:
\1_id\2

Дело в том, что в квадратных скобках мы имеем по одному символу (который не буква и не знак подчёркивания). Поэтому, при замене (если не использовать круглые скобки и в поле Replace просто написать _id) мы бы заменяли не только id, но и символ справа и символ слева от id, то есть съедались бы точки с запятой и прочие важные символы. \1 и \2 заставляет Xcode кроме _id вставить одиночные символы слева и справа (те, которые были слева и справа от оригинальной id).

четверг, 10 февраля 2011 г.

Как сделать один общий проект для нескольких статических библиотек (либ)

Недавно я сумел таки обойти некоторые ограничения Xcode и сделать один общий проект для нескольких статических библиотек (либ).

Ограничения касаются прежде всего такого макроопределения как __IPHONE_3_1 (последние цифры не столь важны, это уже технические моменты - всё зависит от того, начиная с какой версии IOS ваше приложение и библиотеки должны работать).

Если для каждой либы (т.е. библиотеки) вы создаёте свой отдельный Xcode-проект, то в m и mm исходниках (а также в c/cpp - исходниках, если они в своих свойствах выставлены как c.objcpp и cpp.objcpp файлы) макроопределения __IPHONE_... срабатывают безотказно.

То есть вы можете в вашем коде сделать такую проверку:

#ifdef __IPHONE_3_1
sad;flkasjdf;laksjdfa;sldfkja;sdlkfjasd;lkfj; // всякая дрянь, которая не точно компилируется
#endif

Если компилятор будет ругаться на эту дрянь, то значит всё в порядке.

Проблема начинается, когда вы объединяете несколько либ в один проект (то есть для каждой либы добавляете в проект новый Target с указанием имени либы, а потом нужные для этой либы исходники указываете в свойствах как предназначенные именно для этого Target).

Можно искусственным способом заставить ваш проект узнавать макроопределение __IPHONE_3_1

Для этого зайдите в свойства проекта и найдите там раздел GCC 4.2 Preprocessing, а в этом разделе такую строку (слева) Preprocessor Macros. Так вот в поле справа можно добавить такую строку

__IPHONE_3_1=1

Туда же можно добавить и другие важные строки, например __GNUC__=1 или TARGET_OS_IPHONE=1

Если вы не найдёте такой раздел (это увы случается, и я пока не выяснил почему так бывает), то можете сделать по другому. Попробуйте ввести в поле поиска наверху строку GCC_PREPROCESSOR_DEFINITIONS - сразу же должно будет появиться внизу то, что нужно.

среда, 26 января 2011 г.

Xcode vs Visual Studio

Я уже работаю полтора года разработчиком приложений для iPhone (используя единственную официальную среду разработки Xcode). За несколько лет до этого я несколько месяцев работал с Visual Studio.

Да, действительно чувствуется, что в Apple самые главные люди - дизайнеры, а не программисты. Microsoft проявляет больше заботы об удобстве работы программистов с их основным инструментом.

То есть я больше люблю Visual Studio, чем Xcode.

пятница, 14 мая 2010 г.

Перенос C++ шаблонов из Visual C++ в Xcode-проекты (для GCC-компилятора)

Коллеги подсказали на работе, почему GCC-компилятор (используемый в Xcode) иногда ругается на шаблоны, написанные для Visual C++.

В данном случае речь идёт о членах-данных шаблонных классов. Согласно стандарту языка, в телах членов-функций (методов) шаблонных классов перед именем члена нужно обязательно писать this-> (при этом это требование не является обязательным, если вы пишите C++ код в Visual Studio). GCC компилятор же упорно не замечает такие члены в телах функций шаблонных классов до тех пор, пока вы не напишите this-> (после этого всё успешно компилируется).

пятница, 30 апреля 2010 г.

Как автоматически копировать нужные заголовки в нужное место при сборке Xcode-проекта

Сегодня узнал об очень удобной возможности автоматизировать действия при сборке проекта.

Предыстория:

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

Что я хочу автоматизировать:

В моей ситуации нужно копировать только некоторые заголовочные файлы в определённое место (например, в папку /MyLibs/include/QuartzDrawingLib/).

Раньше я делал это вручную (рискуя однажды забыть скопировать обновлённые заголовки, что порождает множество непредсказуемых проблем из-за несоответствия библиотеке устаревшим заголовкам).

Как это можно сделать?

1-й способ (через добавление скрипта):

Посмотрите на дерево Xcode-проекта. Там есть ниже всех исходников Targets (с иконкой, напоминающей красную мишень). Выберите в Targets вашу цель (как правило с названием вашего проекта), нажмите на неё правой кнопкой мыши и выберите из контестного меню Add - > New Build Phase - > New Run Script Build Phase.

После этого появится окно, в которое нужно ввести текст скрипта. Туда вообще можно вводить любые команды, которые вы могли бы вручную набрать в консоли.

Я ввёл примерно следующее:

destDir=/MyLibs/include/QuartzDrawingLib/
if [ -d "$destDir" ]
then
echo "Directory "$destDir" is found"
else
echo "Directory "$destDir" will be created"
mkdir "$destDir"
if [ -d "$destDir" ]
then
echo "Directory "$destDir" is created"
else
echo "Directory "$destDir" is not created!"
echo "Exit script..."
exit 1
fi
fi

echo Copying headers...

cp Classes/SomeClass1.h $destDir
cp Classes/SomeClass2.h $destDir
cp Classes/SomeClass3.h $destDir
cp Classes/SomeClass4.h $destDir
cp Classes/SomeClass5.h $destDir

и так далее (из папки Classes в текущей директории копируются все ТОЛЬКО НУЖНЫЕ МНЕ заголовки в корень системного диска в папку /MyLibs/include/QuartzDrawingLib/

Теперь не нужно это делать каждый раз вручную.

Всё тоже самое можно сделать ВНЕ ПРОЕКТА как отдельный исполняемый скрипт (в виде обычного текстового файла), только перед написанием всех команд не забудьте сверху написать #!/bin/bash
Кроме того, после написания скрипта (т.е. текстового файла ВНЕ ПРОЕКТА) нужно данный текстовый файл сделать исполняемым - для этого выполните в консоли команду:
chmod +x NameOfScriptFile

2-й способ (который значительно проще, но менее надёжный, так как не гарантирует обновление имеющихся копий заголовков, т.е. их приходится удалять и снова нажимать кнопку Build):

Выберите в Targets вашу цель (как правило с названием вашего проекта), нажмите на неё правой кнопкой мыши и выберите из контестного меню Add - > New Build Phase - > New Copy Files Build Phase (после появления новой иконки добавленной фазы, в настройках этой фазы можно указать абсолютный путь куда копировать те файлы, которые вы будете добавлять в эту фазу в дереве проекта).

Hе забывайте, что с помощью скриптов вы можете автоматически выполнять множество других действий, а не только копировать заголовочные файлы.

Как выяснить причину EXC_BAD_ACCESS в Xcode

Нашёл интересную статью (на английском) на http://www.codza.com/how-to-debug-exc_bad_access-on-iphone (там это приводится с рисунками и комментариями читателей).

НАЧАЛО ЦИТАТЫ.

EXC_BAD_ACCESS. Debugging this one is on par with figuring out why the wife says “not tonight, honey.” And they are equally unfortunate situations.

Let’s see what we can do about EXC_BAD_ACCESS.

EXC_BAD_ACCESS happens when a message is sent to an object that has already been released. By the time the error is caught, the call stack is usually gone especially if dealing with multiple threads.

How nice would it be to keep a dummy around after the object is released that could stop execution, tell us what message was sent and show us the call stack… well, there’s a way to do just that.

If you set the NSZombieEnabled environment variable, the Objective C runtime will leave a dummy object behind for every deallocated object. When the zombie object is called, execution stops and you can see the message that was sent to the object and the call stack that tells you where the message came from (it doesn’t tell you where you over released the object, but knowing where the object is called from should get you pretty close to the problem.)

To set this variable, go to the info panel of the executable in xcode, and create a new environment variable in the arguments tab by clicking the plus sign in the lower left corner of the window. Name the variable NSZombieEnabled, type YES for the value and make sure that the checkbox is selected.
set NSZombieEnabled variable

set NSZombieEnabled variable

Go ahead and run your program now (in debug mode, because you need the stack information.) When the over released object is accessed, you get an error message similar to this (xcode debug view):

2009-03-30 02:30:36.172 ninjaJumper[3997:20b] *** -[GameLayer retain]: message sent
to deallocated instance 0x59bf670

This shows the class of the object (GameLayer) and the message sent (retain).

Let’s take a look at the stack now:
call stack

call stack

The methods printed in bold are in your code, the others are in some other API. Here you can see that the object was accessed from [Director touchesBegan:withEvent], where an array was copied (most likely the over released object was in the array.)

This information should get you pretty close to the problem.

Once the problem is fixed, make sure that the NSZombieEnabled variable is disabled. You don’t need to delete it, but make sure that the checkbox is unchecked:
NSZombie disabled

NSZombie disabled

Now about the wife. Good luck there. Try a box of chocolate or load the dishwasher for a couple days.

КОНЕЦ ЦИТАТЫ.

К СОЖАЛЕНИЮ, ДАННЫЙ СОВЕТ ПОЗВОЛЯЕТ ОТСЛЕЖИВАТЬ ИМЕНА Objective C КЛАССОВ. Я ТОЛЬКО ЧТО СДЕЛАЛ ТЕСТОВОЕ ПРИЛОЖЕНИЕ, В КОТОРОМ ПОЛЕЗНЫЕ ОТЛАДОЧНЫЕ СООБЩЕНИЯ ВЫВОДЯТСЯ В КОНСОЛЬ ТОЛЬКО КАСАЕМО Objective C КЛАССОВ:


TestClass *testObj = [[TestClass alloc] init];
[testObj release]; // уничтожили объект перед попыткой использования
[testObj printMsg];

В этом случае в консоль будет выводиться информация
2010-04-28 13:02:08.030 ZombieTest[1353:207] *** -[TestClass printMsg]: message sent to deallocated instance 0x3924880)


В случае же с C++ классом:

TestCppClass *tcpp = new TestCppClass();
delete tcpp;
tcpp = 0;
tcpp- >PrintMsg(); // удивительно, но это работает (на экран выводится тестовое сообщение, так как вероятно функция-член класса способна работать и без создания объекта - ЭТО ЧТО, ОЧЕРЕДНОЙ БАГ Xcode?)
delete tcpp; // тем не менее здесь код спотыкается, так как пытаемся уничтожить объект повторно

в консоль выводится то же самое что и без применения совета из приведённой статьи):
2010-04-28 13:04:45.242 ZombieTest[1476:207] TestClass --- printMsg
ZombieTest(1476,0xa0a7b4e0) malloc: *** error for object 0x3917160: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Что делать, если в Xcode-отладчике невозможно переключиться на другой поток

Лично у меня получается переключиться между потоками, как только я нажму Pause-кнопку (т.е. остановлю приложение). По крайней мере можно увидеть, что происходило в тот момент в разных потоках.

Нашёл некоторое объяснение на http://www.cocoabuilder.com/archive/xcode/248374-debug-problem-in-multithreaded-environment-in-xcode.html

Там такой ответ и совет, надеюсь, программисты умеют читать по-английски:

Sometimes this happens because of the same reason that the backtrace
stack gets bumped off the top of the screen. This is a known problem
that we are investigating. Try toggling the debugger layout (using
the Toggle Debugger Layout command) or deleting the .mode1 file
in your Project's bundle.

вторник, 27 апреля 2010 г.

Как сделать скрипт для компиляции и линковки сразу нескольких Xcode-проектов

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

В Мac OS в командной строке (в терминале) всё делается примерно также, как и в любой Unix-подобной системе.

Чтобы оставаться в терминале, можно даже и не открывать текстовый отдельный редактор, потому что есть встроенные редактор vi (или vim, насколько я знаю, этот редактор очень любят старые Linux-хакеры). Справку по этому редактору можно найти во многих статьях и учебниках (посвящённых Unix/Linux).

В самом верху вашего скрипта (текстового файла, содержащего все необходимые команды для выполнения) введите:

#!/bin/bash

Для того, чтобы добавить в скрипт команду для сборки (компиляции и линковки) Xcode-проекта, добавьте строку (вместо myProject.xcodeproj нужно указать правильный путь к файлу проекта):

xcodebuild -project myProject.xcodeproj -target targetname

(насчёт аргумента, который нужно ввести вместо targetname можно выяснять набрав команду
man xcodebuild

Можно заранее сделать все настройки, открыв проект в среде разработки Xcode (и поставив все необходимые опции, используя графический интерфейс). А потом уже написать в скрипте:

xcodebuild -project myProject.xcodeproj -activetarget

При выполнении этой команды всё будет компилироваться и линковаться точно также, как если бы вы снова открыли ваш проект в среде разработки и нажали на кнопочку "Build".


После того, как напишите и сохраните ваш скрипт (из команд для сборки нескольких проектов), обязательно позвольте ему стать исполняемым файлом, выполнив в терминале команду (при условии, что вместо scriptFileName указан правильный путь к файлу):

chmod +x scriptFileName

Если после компиляции+линковки (т.е. после сборки бинарника) вы видите, что дата создания бинарного файла стоит старая, то это лишь из-за того, что в исходниках или настройках проекта ничего не изменялось со времени прошлой сборки бинарника.

Ну вот собственно и всё.

Xcode — странные выходки отладчика

Отладчик, встроенный в Xcode, иногда вытворяет казалось бы необъяснимые вещи. Например, указатель согласно показаниям отладчика может быть равен нулю в том месте кода, где до этого была проверка, согласно которой в случае нулевого значения указателя код не должен дальше выполняться. Или бывает так, что строка приобретает зловещий вид через некоторое время после её инициализации (этот вид можно увидеть в Memory Browser).

Эти странные выходки Xcode-отладчика возникают по 2-м причинам, которые я успел уже выяснить:

1) Либо какая-то часть бинарного кода статической библиотеке не соответствует исходникам этой библиотеки (иначе говоря, исходники могли поменяться, а библиотеку забыли перекомпилировать).

2) Либо происходит обыкновенное переполнение стека. Тогда отладчик начинает показывать странные значения переменных. По крайней мере, на моей работе такое произошло в дополнительно созданном потоке. С помощью pthread-функций или с помощью класса NSThread можно изменять размер стэка потока перед его созданием потока, так как по умолчанию размер стека равен 512 килобайт. Благо, рядом со мной оказались опытные программисты. Они подсказали, что при переполнениях стека отладчик происходит повреждение данных, поэтому отладчик и показывает всякую чушь

Переименование Xcode-проекта и приложения (для iPhone)

Можно легко переименовывать основной контейнер проекта (который в Windows/Unix выглядит как обычная папка, а в Finder из Mac OS выглядит внешне как файл с расширением *.xcodeproj) - обычно это не вызывает никаких проблем.

Это может пригодиться, если вы делаете в Xcode приложение или библиотеку для Mac OS и для iPhone, используя общие исходные файлы. В таком случае достаточно сделать копию *.xcodeproj-контейнера и дать ему другое имя.

Несколько иначе обстоит дело при попытке изменить имя приложения для iPhone, т.е. название программы, как оно отображается в списке приложений на экране iPhone. Сейчас в новой версии iPhoneSDK в меню Xcode есть возможность переименовать проект (и вероятно название программы) - но я пока не исследовал эту возможность.

Далее я расскажу про старый способ переименовать проект, который я уже проверил несколько раз (об этом я узнал из зарубежных источников).

Скопируйте папку всего проекта (не только вышеупомянутый контейнер с расширением *.xcodeproj, но и все исходники с ресурсами) в надёжное место — вдруг что-то получится не так, как вы хотели. Вообще, полезно всегда делать копии всех важных файлов как можно чаще (или использовать систему контроля версий).

Войдите в ту папку, в которой вы будете переименовывать проект. Давайте будем считать для примера, что мы хотим переименовать AppleSample в MyCoolApp.

1) Переименуйте AppleSample.xcodeproj в MyCoolApp.xcodeproj.
2) Переименуйте AppleSample_Prefix.pch в MyCoolApp_Prefix.pch
3) Удалите папку build folder (используя Finder).
4) Откройте.xcodeproj как контейнер-папку (используя контекстное меню, например нажав на правую кнопку мыши, в зависимости от настроек Mac OS). В этой папке есть несколько файлов (обычно 3 или 4). Их нужно будет редактировать в текстовом редакторе (желательно с подсветкой синтаксиса для вашего же удобства — можно открыть даже с помощью Xcode).
5) Откройте project.pbxproj как текст и переименуйте все встречающиеся строки со старым именем AppleSample на новое имя MyCoolApp. Лучше не используйте для этого операцию «Найти и заменить (find an replace)». Имейте ввиду, что если вы захотите изменить строки, содержащие AppleSampleAppDelegate.h и AppleSampleAppDelegate.m, то изменение этих строк вынудит вас переименовать файлы с этими именами физичеки (поменять имена на те, что вы укажете в строках вместо старых).
6) Откройте файл с расширением.pbxuser (имя этого файла содержит ваше системное имя пользователя). Повторите все предыдущие шаги по редактированию строк.
7) Откройте все xib-файлы (их ещё принято называть nib-файлами) как текстовые или source файлы и повторите все предыдущие шаги по редактированию строк (это особенно актуально, если вы осмелились переименовать исходники главного делегата приложения).
8) Попробуйте после всего этого открыть проект в Xcode, и сделайте Clean и Build.

Как совмещать C++ и Objective C код в одном файле (классе)

Есть 2 способа, как совмещать C++ и Objective C код в одном исходнике:

1) При добавлении в Xcode-проект нового Objective C класса (который будет включать в себя C++ код) дайте файлу реализации расширение.mm (а не.m как предлагается по умолчанию). Кроме того, можно смело переименовать в дереве Xcode-проекта файл, изменив расширение с m на mm.

2) Если вам нужно использовать Objective C код в C++ классе (файл реализации которого будет иметь расширение.cpp) то в дереве проекта нажмите правую кнопку мыши или сделайте иное действие (в зависимости от настроек Mac OS) чтобы вызвать контекстное меню. В контекстном меню выберите Get Info. Появится окошечко, в котором нужно поменять тип файла с cpp.cpp на objcpp.cpp. Кстати, это позволит коду узнавать #ifdef __IPHONE_3_1 (или какая у вас там версия iPhone OS), что необходимо, если вы работаете в коллективном проекте, где нужно писать переносимый код для разных платформ.

Постоянные читатели