18 февр. 2014 г.

Хакинтош - Mac OS на PC

Многим знакома ситуация, когда Вы от друзей, из Интернет или откуда-то ещё узнали о чудесном компьютере от Apple, но не можете решиться его приобрести. Бывает, что у вас нет приятеля, готового дать Вам попользоваться своим Mac, чтобы Вы решили для себя, нужно оно Вам или нет. Тогда ключевой причиной нерешительности является страх потратить немаленькие деньги на продукт, который впоследствии может вам и не понравиться.
Над ключевыми шагами к возможности установки Mac OS X на сторонних системах работала масса людей, все из сообщества OSx86. Нам не известны их имена, но их псевдонимам выразят благодарность многие, у кого хакинтош был промежуточным этапом до настоящего Mac. Так, Maxxuss, SemjaZa и JaS были первыми, кто смог заставить EFI — более продвинутую замену BIOS, на которой построена OS X — работать на архитектуре x86. Позже энтузиастам Mifki, Semthex и Rufus удалось перенести на x86 и ядро XNU. Но настоящая эра хакинтоша для человека началась с выходом установочных DVD от JaS и tubgirl, которые позволяли без боли в зубах установить Mac OS X 10.4.8 на множество компьютеров на процессорах Intel или AMD.
Сразу попробуйте найти модель материнской платы и процессора, которые вы собираетесь использовать. Или наоборот, подберите самый оптимальный вариант из того, что у вас имеется на руках. Если вашего процессора нет в списке, то велика вероятность, что ничего не получится. Если же вы нашли его среди указанных, то определитесь с материнской платой, ориентируясь на комментарии в графе Fully Working w/o Patch, и прочитайте инструкции в графе Notes таблицы плат. Напротив каждой платы будет перечислено, что именно работает или не работает в Mac OS X на такой плате, а также указан оптимальный способ установки, включая необходимые дистрибутивы. От вас требуется просто скачать указанный дистрибутив и прожечь его на диск.
Обычно, после установки и успешной загрузки Mac OS X на PC возникают новые проблемы, с которыми приходиться считаться. По версии MacSpoon, три типичных проблемы свежей установки хакинтоша — это неработающая видеокарточка, неработающая сетевая карточка и неработающий USB. Но правильно подобранное железо и наличие драйверов под него в корне меняют ситуацию. Так что дерзайте. Ставьте OS X. Потом Xcode, и погнали программировать, ведь это очень интересно. Удачи.

NSCache контейнер - кэш

Объект NSCache является контейнером или кэшем, который хранит пары “ключ-значение”, аналогично классу NSDictionary. Разработчики часто используют кэши для временного хранения объектов, создание которых является дорогостоящим. Повторное использование этих объектов может обеспечить повышение производительности, потому что их значения не должны быть пересчитаны. Однако, эти объекты не являются критическими для приложения и могут быть удалены, если память ограничена. Если такие объекты удалить, их значения нужно вычислить заново, когда это необходимо.
Пока пара ключ-значение в кэше, кэш поддерживает сильную ссылку на него. Общие типы данных, хранящиеся в объектах NSCache — это объекты, которые реализуют протокол NSDiscardableContent. Хранение объектов этого типа в кэше имеет преимущества, поскольку их содержимое может быть удалено, если они больше не нужны, что приводит к экономии памяти. По умолчанию объекты, реализующие NSDiscardableContent, автоматически удаляются из кэша, если их содержимое удаляется, хотя эта политика автоматического удаления могут быть изменена.
Объекты NSCache имеют несколько отличий от других изменяемых коллекций. Класс NSCache включает в себя различные политики автоматического удаления, обеспечивающие использование не слишком большого количества памяти системы. Система автоматически осуществляет эти политики, если память необходима другим приложениям. При вызове эти политики удаляют некоторые элементы из кэша, сводя к минимуму использование памяти. Вы можете добавлять, удалять и запрашивать элементы из кэша из разных потоков без необходимости блокировки кэша. В отличие от объекта NSMutableDictionary, кэш не копирует ключевые объекты, добавленные в него.
Методы класса
Изменение имени кэша

Название
Описание
- name
Возвращает имя кэша.
- setName:
Устанавливает имя кэша из заданной строки.

Получение кэшированных значений


Название
Описание
- objectForKey:
Возвращает значение, связанное с указанным ключом.

Добавление и удаление кэшированных значений



Название
Описание
- setObject:forKey:
Устанавливает значение указанного ключа в кэше.
- setObject:forKey:cost:
Устанавливает значение указанного ключа в кэше и связывает пару ключ-значение с указанной стоимостью.
- removeObjectForKey:
Удаляет значение из кэша по указанному ключу.
- removeAllObjects
Очищает кэш, удалив все объекты.
Управление размером кэша


Название
Описание
- countLimit
Возвращает максимальное количество объектов, которые в настоящее время может содержать кэш.
- setCountLimit:
Задаёт максимальное число объектов, которое кэш может содержать.
- totalCostLimit
Возвращает максимальную общую стоимость, которую может иметь кэш до начала вытеснения объектов.
- setTotalCostLimit:
Задаёт максимальную общую стоимость, которую может иметь кэш до начала вытеснения объектов.

Управление удаляемым содержимым


Название
Описание
- evictsObjectsWithDiscardedContent
Возвращает логическое значение, указывающее, будет ли кэш автоматически вытеснять объекты, содержимое которых было удалено.
- setEvictsObjectsWithDiscardedContent:
Устанавливает логическое значение, указывающее, будет ли кэш автоматически вытеснять объекты, содержимое которых было удалено.

Управление делегатом

Название
Описание
- delegate
Возвращает делегат кэша.
- setDelegate:
Устанавливает заданный объект делегатом кэша.

17 февр. 2014 г.

NSArchiver кодирование объектов

Класс NSArchiver, конкретный подкласс NSCoder, предоставляет способ для кодирования объектов в архитектурно независимый формат, который может храниться в файле. Объект класса NSArchiver сохраняет архивные данные в изменяемый объект данных, объект класса NSMutableData. После кодирования объектов, объект NSArchiver может записать этот изменяемый объект данных непосредственно в файл, или можно использовать эти данные по-другому. Класс NSUnarchiver служит для декодирования объектов из объектов, хранящих данные. В Mac OS X v10.2 и более поздних версиях, NSArchiver и NSUnarchiver были заменены NSKeyedArchiver и NSKeyedUnarchiver.

Методы класса:

Инициализация NSArchiver


Название
Описание
- initForWritingWithMutableData:
Возвращает архиватор, инициализированный для кодирования потока и сведений о версии в указанный объект изменяемых данных.

Архивирование данных

Название
Описание
+ archivedDataWithRootObject:
Возвращает объект данных, содержащий закодированную форму графа объектов для заданного корневого объекта.
+ archiveRootObject:toFile:
Создает временный экземпляр NSArchiver и архивирует граф объектов при помощи кодирования в объект данных и записи результирующего объекта данных в указанный файл.
- encodeRootObject:
Архивирует заданный объект, а также все объекты, к которым он подключен.
- encodeConditionalObject:
Условно архивирует заданный объект.

Получение архивных данных


Название
Описание
- archiverData
Возвращает архивные данные текущего объекта.

Замена классов или объектов


Название
Описание
-classNameEncodedForTrueClassName:
Возвращает имя класса, используемого для архивирования экземпляров класса с правильным заданным именем.
- encodeClassName:intoClassName:
Кодирует заменяющее имя для класса с заданным правильным именем.
- replaceObject:withObject:
Позволяет текущему архиверу закодировать заданный объект так, как будто бы он является другим заданным объектом.

16 февр. 2014 г.

NSAffineTransform аффинные преобразования


Класс NSAffineTransform предоставляет методы для создания, объединения и применения аффинных преобразований. Преобразование определяет, как точки в одной системе координат трансформируются в точки в другой системе координат. Аффинное преобразование — особый тип преобразования, которое сохраняет параллельные линии в трансформируемом контуре, но не обязательно сохраняет длины или углы. Масштабирование, вращение и перенос являются наиболее часто используемыми действиями, поддерживаемыми аффинными преобразованиями, но также возможен и сдвиг объектов.
Методы класса:

Создание объекта NSAffineTransform
Название
Описание
+ transform
Создает и возвращает новый объект NSAffineTransform инициализированный единичной матрицей.
- initWithTransform:
Инициализирует матрицу текущего объекта с помощью другого объекта transform и возвращает текущий объект.

Накопительные преобразования

Название
Описание
- rotateByDegrees:
Применяет коэффициент поворота (измеряется в градусах) к матрице преобразования текущего объекта.
- rotateByRadians:
Применяет коэффициент поворота (измеряется в радианах), к матрице преобразования текущего объекта.
- scaleBy:
Применяет указанный коэффициент масштабирования для осей x и y к матрице преобразования текущего объекта.
- scaleXBy:yBy:
Применяет коэффициенты масштабирования для каждой оси матрицы преобразования текущего объекта.
- translateXBy:yBy:
Применяет указанный коэффициент переноса к матрице преобразования текущего объекта.
- appendTransform:
Добавляет заданную матрицу к матрице текущего объекта.
- prependTransform:
Добавляет заданную матрицу к матрице текущего объекта.
- invert
Инвертирует матрицу текущего объекта.

Преобразование данных и объектов

Название
Описание
- transformPoint:
Применяет преобразование текущего объекта к указанному объекту NSPoint и возвращает результаты.
- transformSize:
Применяет преобразование текущего объекта к указанному объекту NSSize и возвращает результаты.

Доступ к структуре трансформации


Название
Описание
- transformStruct
Возвращает матричные коэффициенты, хранящиеся в матрице текущего объекта.
- setTransformStruct:
Заменяет значения коэффициентов матрицы преобразования текущего объекта указанными значениями.

15 февр. 2014 г.

Урок по работе с NSTableVIew. Добавление данных

Для пользователя очень важно, чтобы данные были представлены в удобном виде. В этой статье мы рассмотрим как создается табличное представление данных в OS X. Урок предназначен для тех кто уже более-менее знаком с Objective-C, и протоколами. Для начала создадим новый проект в Xcode (Cocoa). Назовем его, например, TableViewAddDataTest. Добавим на нашу форму TableView контрол. Выставим размеры согласно нашей форме (окну).



Установим количество колонок в таблице равным 1-й (Attribute Inspector -> Columns). Дальше заходим в Connections Inspector и соединяем (делаем связь) нашему аутлету dataSource и делегату delegate с AppDelegate.

А теперь о главном. "Нельзя просто так взять и добавить строчку в таблицу напрямую", проще всего и быстрее будет пакетная передача объектов таблице, что чаще в роли пакетов объектов выступают массивы, в нашем случае NSArray (для одной колонки).

И так - поехали. В наш хидер-файл AppDelegate.h добавим протокол (делегат), объявим наш массив dataArray и объект myTableView через который будем работать с таблицей и будем использовать методы NSTableView класса:

//
//  AppDelegate.h
//  TableViewAddDataTest
//
//  Created by Sergey Krasiuk on 15.02.14.
//  Copyright (c) 2014 Sergey Krasiuk. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource>
{
    NSArray *dataArray;
    NSTableView *myTableView;
}

@property (assign) IBOutlet NSWindow *window;

@end

Главное что нужно помнить при работе с табличным представлением, это - два обязательных метода, без которых в таблице не появятся данные:


//  Нужно передать табличному представлению количество строк
//  для отображения данных, в нашем случае это колличество элементов в массиве.
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView


//  Возвращает объект (данные которые будут отображаться в строке)
//  для каждой строчки row нашего табличного представления
- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row

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


- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
    return [dataArray count];
}

Следующий шаг. Мы должны передать для каждой строчки таблицы данные которые хранятся в нашем массиве. Т.е. человеческим языком индекс строки row будет равен индексу элемента нашего массива данных. В нашем случае мы передадим объекты типа NSString для каждой строки:


- (id) tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSString *arrayString = [dataArray objectAtIndex:row];
    return arrayString;
}


Проинициализируем наш массив (заполним его данными), т.к. пока что передавать нам в таблицу нечего (лучше всего инициализацию делать в методе init (в нашем случае), не в applicationDidFinishLaunching, при запуске массив не успеет заполнится данными и мы в таблице ничего не получим):


- (id) init
{
    self = [super init];
    
    if (self)
    {
        dataArray = [[NSArray alloc] initWithObjects:@"Первая строка", @"Вторая строка", @"Третья строка", @"Четвертая строка", @"Пятая строка", @"Шестая строка", nil];
    }
    
    return self;
}

Запускаем наш проект, и должно получится вот такое:
Нюанс в добавлении или удалении элементов (строк) из таблицы состоит в том чтобы вычислить выделенный объект (строку таблицы) и получить его индекс. Потом удалить/добавить объект под этим индексом из/в массива и вызвать в том же методе (в котором удаляем/добавляем объекты из массива) reloadTable. Табличное представление обновит данные из массива и покажет нужный результат:

- (void) tableViewSelectionDidChange: (NSNotification *) notification

Удачи в начинаниях. Еще один из примеров NSTableView


14 февр. 2014 г.

@property свойства класса


Ключевое слово @property позволяет объявить свойства класса в языке Objective C. По своей сути свойства являются средством написания кода, позволяющим удобно обращаться к полям класса, не нарушая принципа инкапсуляции и не используя синтаксис вызова методов. Свойства не обязательно должны базироваться на полях класса. Они могут, например, вычисляться во время каждого вызова. Основной смысл использования свойств – более удобный синтаксис в сравнении с обычными вызовами методов. Возможность использовать свойства появилась в языке Objective C начиная с версии 2.0. Для лучшего понимания принципов работы свойств рассмотрим несколько примеров. Предположим, у нас есть класс Car, содержащий поле speed для хранения скорости автомобиля. Тогда объявление этого класса будет выглядеть так:
@interface Car : NSObject
{
double speed;
}
-(double) getSpeed;
-(void) setSpeed:(double)s;
@end
Сообщения getSpeed и setSpeed позволяют читать и изменять закрытое поле speed, реализовывая принцип инкапсуляции. Реализация данного класса может выглядеть следующим образом:
@implementation Car
-(void) setSpeed:(double)s
{
if ( s>=0 )
{
speed = s;
}
}
-(double) getSpeed
{
return speed;
}
@end
Создание экземпляра этого класса и использование поля могут быть такими:
Car *car = [[Car alloc] init];
[car setSpeed:105];
NSLog(@"%f", [car getSpeed]);
[car release];
На приведенном выше примере можно увидеть, что чтение значений из полей класса и занесение новых значений синтаксически не очень удобно. Гораздо удобнее было бы напрямую обратиться к полям класса при помощи оператора -> Но тогда поля класса пришлось бы сделать открытыми и было бы невозможно контролировать значения, заносимые в поля. Применение свойств как раз и должно решить эту проблему. С использованием ключевого слова @property объявление класса примет такой вид:
@interface Car : NSObject{ double speed;} @property double speed; @end
Как видно из примера, при объявлении свойства указывается тип свойства и в данном случае он совпадает с типом поля класса. Так же Objective C допускает одинаковые названия свойств и полей классов. С учётом сделанных изменений, реализация класса будет такой:
@implementation Car
@synthesize speed;
@end
Упрощение кода в данном случае заметить не трудно. Мы просто убрали реализацию методов доступа к полю speed и заменили её на автоматическую генерацию поля при помощи ключевого слова @synthesize. Теперь попробуем воспользоваться созданным свойством:
Car *car = [[Car alloc] init];
car.speed = 45.5;
NSLog(@"%f", car.speed);
[car release];
Вот ради чего всё затевалось. Теперь мы можем обращаться к полю класса при помощи удобного оператора “точка”. В этом и есть основной смысл свойств. Но в этом коде всё ещё есть проблемы. Дело в том, что в поле speed можно запросто занести отрицательные значения. И данное автоматически сгенерированное свойство никак не может этому помешать. Такая реализация свойства не очень-то и полезна для класса Car. Поэтому переделаем реализацию, добавив в неё аксессоры для доступа к полю.
@implementation Car
-(void) setSpeed:(double)s
{
if(s>0) speed = s;
}
-(double) speed
{
return speed;
}
@end
Теперь свойство не позволит заносить в поле класса отрицательные значения. Несмотря на то, что кода стало больше, свойство защищает поле класса от некорректных значений. На примере можно увидеть, что имя метода, возвращающего значение, совпадает с именем свойства, а имя метода, записывающего новые значения почучается добавлением слова set в начало имени метода, название свойства начинается с большой буквы. В принципе, названия методов-аксессоров можно изменить. Для этого придётся внести изменения в объявление свойства:
@interface Car : NSObject
{
double speed;
}
@property (getter = getSpeed, setter = setSpeed:) double speed;
@end
После таких изменений объявления свойства метод, возвращающий значение свойства должен называться getSpeed, а метод задающий значение свойства, должен называться setSpeed.