Масштабирование iOS-приложений: Как это делал Рамблер?


Настольная ОС компании Apple

Перед началом майских праздников я провел 5 плотных дней за написанием приложения под iOS и Mac для конкурса. Разработка шла планомерно, к последнему дню работа приложения меня начала более-менее удовлетворять. Я решил отложить отправление на утро самого последнего дня, чтобы сделать это со свежой головой (там нужно было еще приложить текстовое описание). Утром, за несколько часов до поезда в отпуск, я сел и со спокойной душой сделал финальную обкатку основного функционала. И тут мне показалось хорошей идеей потестить, как будет вести себя приложение на абсолютно другой машине, на которой не велась разработка. Я архивирую свое приложение, перекидываю его на другой Mac и… оно не запускается. С супер-информативной ошибкой "Image not found" и путём явно указывающим на проблему с dylib. Итак: 3 часа до поезда и не запускающиеся по непонятным причинам приложение. Почему это произошло, как этого можно было бы избежать и как я справился с этой проблемой — обо всём этом под катом.




char near* и int huge*. Виртуальная память поделена на страницы, типичный размер которых 4 KiB, и по умолчанию они не отображены на физическую память (mapping), так что работать с ними не получится. Чтобы посмотреть текущие отображённые интервалы адресов у процесса, в Linux смотрим /proc/<pid>/maps, в OS X vmmap <pid>. У каждого интервала адресов есть три вида защиты: от исполнения, от записи и от чтения. Как видно, самый первый интервал, начинающийся с load address (соответствующий сегменту .text у ELF в Linux, __TEXT у Mach-O в OS X), доступен на чтение и исполнение — очень логично. Ещё можно увидеть, что стек по сути ничем не отличается от других интервалов, и можно быстро вычислить его размер, вычтя из конечного адреса начальный. Отображение страниц выполняется с помощью mmap/munmap, а защита меняется с помощью mprotect. Ещё существуют brk/sbrk, deprecated древние пережитки прошлого, которые изменяют размер одного-единственного интервала «данных» и в современных системах эмулируются mmap’ом.
«Есть внешний жесткий диск и 2 тачки (одна на Win, вторая на OS X). Доступ к диску нужен с обеих машин.»


pip, npm и gem не подходили в силу языка самой утилиты — bash. Тогда стало понятно, что нужно распространять свое приложение в том числе и через системные пакетные менеджеры. Для Mac — в силу отсутствия встроенного — таких пакетных менеджеров несколько. И у каждого из них есть свои особенности и недостатки. И в первой части я хочу более подробно остановиться на Homebrew, и как создавать пакеты для него..tar.gz, .deb и .rpm. О чем я расскажу во второй части.

[button addTarget:self action:[self ax_lambda:^(UIButton *sender, UIEvent *event){
NSLog(@"click on button %@, event = %@", sender, event);
}] forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:[self ax_lambda:^{
NSLog(@"click");
}] forControlEvents:UIControlEventTouchUpInside];
__block NSInteger sum = 0;
[self performSelector:[self ax_lambda:^(NSNumber *argA, NSNumber *argB) {
sum = [argA integerValue] + [argB integerValue];
}] withObject:@(2) withObject:@(3)];
//sum — 5
SEL selSum = [self ax_lambda:^NSInteger(NSInteger argA, NSInteger argB){
return argA + argB;
}];
NSInteger(*funcSum)(id, SEL, NSInteger, NSInteger) = (NSInteger(*)(id, SEL, NSInteger, NSInteger))objc_msgSend;
NSInteger sum2 = funcSum(self, selSum, 2, 3);
//sum2 — 5




$ ls -la /private
total 0
drwxr-xr-x@ 6 root wheel 204 Oct 1 10:20 .
drwxr-xr-x 33 root wheel 1190 Nov 4 15:56 ..
drwxr-xr-x 106 root wheel 3604 Nov 13 18:04 etc
drwxr-xr-x 2 root wheel 68 Aug 23 02:28 tftpboot
drwxrwxrwt 14 root wheel 476 Nov 16 10:55 tmp
drwxr-xr-x 25 root wheel 850 Nov 4 17:02 var
$