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

пятница, 9 декабря 2016 г.

Не работает Playground? Восстанавливаем

Часто с моим Xcode бывает следующая ситуация: Playground вроде бы и работает, но не показывает результаты. В этом случае мне помогает вот такая последовательность действий:

  • Выходим из Xcode.app и Simulator.app;
  • В терминале: 
    $ rm -fr ~/Library/Developer/*
    $ sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService
    $ rm -rf ~/Library/*/CoreSimulator
  • ЗапускаемXcode (и Simulator.app);
Ну, что еще добавить? Будьте осторожны с командой rm. 

пятница, 25 ноября 2016 г.

Язык Swift: массивы и словари


Рассмотрим коротко массив:
  • Массив - это упорядоченный список значений (величин, элементов);
  • Каждая величина в массиве позиционируется целым числом или индексом. Первая величина в списке имеет индекс 0;
Проиллюстрируем это куском из Playground:
var str = "Hello, playground"
var myArray1: Array<String> = ["myString1","myString2"]
var myArray2: [String] = ["myString3", "myString4"]
let myArray3: [String] = ["myString5", "myString6"]
let myArray4 = ["myString7","myString8"]
var myArray5 = [String]()
var myArray6 = Array<String>()
var myArray7: Array<AnyObject>
Перечислим типичные действия, что мы можем применить к массивам:
  • С помощью свойства count определяется число элементов в массиве;
  • Получение значения элемента массива с помощью индекса;
  • Добавление нового элемента к массиву с помощью функции append(_) или оператора +=;
  • Удаление выбранного элемента с помощью функции remove(at:);
  • Добавление нового элемента в массив в указанную позицию помощью функции insert(_,at:);
  • Изменение значения выбранного элемента с помощью оператора =;
  • Просмотр содержимого массива с помощью цикла for-in;
Проиллюстрируем это куском из Playground:
print("number elements in the array: \(myArray1.count)")
print("\(myArray1[1])")
myArray1.append("myString9")
myArray1+=["myString10"]
myArray1.remove(at: 0)
myArray1.insert("myString11", at: 1)
myArray1[0]="myString12"
for i in myArray1{
    print("\(i)")
}
Аналогично рассмотрим словарь:
  • Словарь - это неупорядоченный список абстрактных пар ключ-значение (ключ-величина, ключ-элемент);
  • Как в массиве элемент определяется по индексом, величиной целого типа, так и в словаре элемент определяется ключом, величиной любого типа. Я думаю, что можно говорить об массиве как частном случае словаря;
  • На практике в большинстве случаев тип ключа - это String;

Проиллюстрируем это куском из Playground:
var myDictionary1: Dictionary<String, String> = [:]
var myDictionary2: Dictionary<String, String> = ["myKey1":"myValue1","myKey2":"myValue2"]
var myDictionary3: [String: String] = ["myKey3":"myValue3","myKey4":"myValue4"]
var myDictionary4 = [String:String]()
var myDictionary5 = Dictionary<String, String>()

Перечислим типичные действия, что мы можем применить к словарям:
  • С помощью свойства count определяется число пар в словаре;
  • Получение значения элемента с помощью ключа;
  • Изменение значения элемента с данным ключом с помощью функции updateValue(_,forKey:) или оператора =;
  • Добавление новой пары ключ-значение;
  • Удаление пары пары ключ-значение с помощью функции removeValue(forKey:) либо присваиванием удаляемому элементу значения nil;
  • Просмотр содержимого словаря с помощью цикла for-in;
Проиллюстрируем это куском из Playground:
print("number elements in the dictionary:\(myDictionary2.count)")
print("\(myDictionary2["myKey2"]!)")
myDictionary2.updateValue("newMyValue2", forKey: "myKey2")
print("\(myDictionary2["myKey2"]!)")
myDictionary2["myKey2"] = "new2MyValue2"
print("\(myDictionary2["myKey2"]!)")
myDictionary2["myKey5"] = "myValue5"
myDictionary2.removeValue(forKey: "myKey1")
let arrayOfMyKeys = [String] (myDictionary2.keys)
let arrayOfMyValues = [String] (myDictionary2.values)
for i in arrayOfMyKeys{
    print("\(myDictionary2[i]!)")
}


среда, 5 октября 2016 г.

Чистый десктоп в Mac OS X

Часто советуют для ускорения работы мака очистить десктоп от всех файлов на нем или сделать их невидимыми (Зачем нужен тогда этот десктоп вообще?). С терминала добиться этой невидимости можно такой командой:
#defaults write com.apple.finder CreateDesktop -bool false
#killall Finder
Вернуть все назад можно так:
#defaults write com.apple.finder CreateDesktop -bool true
#killall Finder

суббота, 11 июля 2015 г.

Сцены OpenGL в Mac OS X

Ну раз говорится про Mac OS, значит программировать будем в cocoa на языке Objective-C. Cоздадим простейшее приложение OpenGL, рисующее на "сцене" куб. Откроем среду разработки XCode и в меню выберем создать новый проект. В списке предложений находим Cocoa Application. Жмем Next.
Выбираем именем рашего проекта CocoaOpenGL и языком разработки объектный си. Далее произвольно заполняем остальные пустые поля. Жмем Next.

Видим "пустой" каркас нашего будущего приложения: 

Во вкладке Build Settings находим поле Linked Frameworks and Libraries и в появившемся списке выбираем OpenGL.framework . Фреймворк, как вы догадались, это заголовочные файлы и бинарные библиотеки для OpenGL .
 Далее создаем пустые заголовочный и реализующий класс Сube файлы из меню "создать новый файл". Класс Cube и является классом, реализующим OpenGL сцену.
Задаем имя CocoaOpenGL.h . Жмем Next:
Это мы создали заголовочный файл. Теперь аналогично создаем файл реализации(эти оба файла пока пусты):
Жмем Next:
 Пишем в поле имени CocoaOpenGL . Жмем Next:
 И, наконец, create, мы увидим пустой файл реализации:
 Новый заголовочный файл заполняем таким содержимым:
@interface Cube : NSOpenGLView
{
    bool        initialized;
    float        rotation[3];
}
+ (NSOpenGLPixelFormat*) basicPixelFormat;
- (void) drawRect: (NSRect) bounds;
- (void) resizeGL:(NSRect)rect;
- (id)initWithFrame:(NSRect)frameRect;
@end
Файл реализации делаем пока таким:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "CocoaOpenGL.h"
#import <OpenGL/gl.h>
#import <OpenGL/glu.h>
@implementation Cube
+ (NSOpenGLPixelFormat*) basicPixelFormat{
}
- (void) resizeGL:(NSRect)rect{
}
- (id)initWithFrame:(NSRect)frameRect{
}
- (void)drawRect:(NSRect)rect {
[super drawRect:rect];
// Здесь будет рисующий код
}
@end
Далее заполняем пустые тела функций следующим содержанием. basicPixelFormat :
    static NSOpenGLPixelFormatAttribute    attributes[] =   
    {
        //NSOpenGLPFAWindow,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
        (NSOpenGLPixelFormatAttribute)nil
    };
    return ([[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]);
initWithFrame :
     NSOpenGLPixelFormat    *pf;
     pf   = [Cube basicPixelFormat];
     self = [super initWithFrame: frameRect pixelFormat: pf];  
     return (self);
drawRect :
    int            width, height;
    int            i, j;       
    float         aspectRatio;

    if (!initialized)
    {
        rotation[0] = 45.0f;
        rotation[1] = 45.0f;
        rotation[2] = 45.0f;
        initialized = true;
    }

    width  = rect.size.width;
    height = rect.size.height;
 
    glViewport(0, 0, width, height);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    aspectRatio = (GLfloat)width/(GLfloat)height;
    //  gluPerspective(100.0f, aspectRatio, 1, 2);
    if(width <= height)
    {
        glOrtho(-2.0f, 2.0f, -2/aspectRatio, 2/aspectRatio, 2.0f, -2.0f);
    }
    else
    {
        glOrtho(-2*aspectRatio, 2*aspectRatio, -2.0f, 2.0f, 2.0f, -2.0f);
    }
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(rotation[0], 1.0f, 0.0f, 0.0f);
    glRotatef(rotation[1], 0.0f, 1.0f, 0.0f);
    glRotatef(rotation[2], 0.0f, 0.0f, 1.0f);
    // рисуем куб
    glEnable(GL_DEPTH_TEST); 
    glBegin(GL_QUADS);
    for (i = 0; i < 6; i ++)
    {
        glColor3fv(colors[i]);
        for (j = 0; j < 4; j ++)
            glVertex3fv(corners[sides[i][j]]);
    }
    glEnd();  
  
    glFlush();
    //[[self openGLContext]flushBuffer];

Обратите внимание, что функция resizeGL - пуста. Код, который реагирует на изменение собственно сцены (не так в Линуксе и я Windows), находится теле основной рисующей функции drawRect. 
Также после директив импорта в файле реализации вставляем такие строки:
static const GLfloat    corners[8][3] =   
{
    {  1.0f,  1.0f,  1.0f },    // Front top right
    {  1.0f, -1.0f,  1.0f },    // Front bottom right
    { -1.0f, -1.0f,  1.0f },    // Front bottom left
    { -1.0f,  1.0f,  1.0f },    // Front top left
    {  1.0f,  1.0f, -1.0f },    // Back top right
    {  1.0f, -1.0f, -1.0f },    // Back bottom right
    { -1.0f, -1.0f, -1.0f },    // Back bottom left
    { -1.0f,  1.0f, -1.0f }     // Back top left
};
static const int    sides[6][4] =   
{
    { 0, 1, 2, 3 },                // Front
    { 4, 5, 6, 7 },                // Back
    { 0, 1, 5, 4 },                // Right
    { 2, 3, 7, 6 },                // Left
    { 0, 3, 7, 4 },                // Top
    { 1, 2, 6, 5 }                 // Bottom
};
static const GLfloat    colors[6][3] = 
{
    { 1.0f, 0.0f, 0.0f },        // Red
    { 0.0f, 1.0f, 0.0f },        // Green
    { 1.0f, 1.0f, 0.0f },        // Yellow
    { 0.0f, 0.0f, 1.0f },        // Blue
    { 1.0f, 0.0f, 1.0f },        // Magenta
    { 0.0f, 1.0f, 1.0f }         // Cyan
};
Далее идем в Main.storyboard:
 Добавляем OpenGL View c хранилища элементов управления главный вид приложения. В правом верхнем углу среды разработки в поле Custom Class указываем на класс Cube (при выделенном элементе управления OpenGL View)
 Далее на вкладке Build Settings поле Objective-C Automatic Reference Counting в значение No
 Для нашего OpenGL View элемента надо установить поле Depth в любое не-none значение:
 Компилируем, запускаем и видим:

пятница, 19 июня 2015 г.

Комбинации клавиш необходимые для комфортной работы в Mac OS X

  • Вызвать mission control: ctrl+"стрелка вверх";
  • Перейти на рабочий стол слева (если он создан в mission control):                                    ctrl+"стрелка влево";
  • Перейти на рабочий стол справа (если он создан в mission control):ctrl+"стрелка вправо";
  • Показать рабочий стол: F11;
  • Вызвать dashboard: F12;
  • Переместить фокус в меню: ctrl+F2;
  • Переместить фокус в dock: ctrl+F3;
  • Перейти к следующему несвернутому окну данного рабочего стола: ctrl+F4;
  • Перейти к  следующему несвернутому окну данного приложения: command+` ;
  • Переключиться между запущенными приложениями: command+tab;
  • Переместить фокус в меню статуса: ctrl+F8;
  • Поменять раскладку клавиатуры: command+space;
  • Вызвать spotlight: ctrl+space;
  • Убить текущее зависшее приложение: option+command+shift+esc;
Конечно вы можете поменять эти комбинации клавиш в system preferences. Здесь представлены установки по умолчанию. Также по умолчанию отсутствуют горячие клавиши для следующих операций: 
  • Вызвать launch pad;
  • Вызвать notification center;
  • Усыпить дисплей;
Я бы рекомендовал их определить для этих трех последних пунктов.Также очень удобной является комбинация:  
  • "Перейти в директорию" - shift+command+g;
По умолчанию в finder дерево файловой структуры частично невидно. Иногда это удобно, иногда - нет. На тот случай, когда вам надо переместиться в директорию, которая "невидима", эта комбинация клавиш незаменима.
Уверен - твердое знание этих комбинаций ускорит и сделает более комфортной вашу работу.
Кстати, обратите внимание, что клавиша ctrl более "крута", чем command.