summaryrefslogtreecommitdiffhomepage
path: root/ru-ru
diff options
context:
space:
mode:
Diffstat (limited to 'ru-ru')
-rw-r--r--ru-ru/bash-ru.html.markdown284
-rw-r--r--ru-ru/javascript-ru.html.markdown4
-rw-r--r--ru-ru/objective-c-ru.html.markdown654
-rw-r--r--ru-ru/python3-ru.html.markdown2
4 files changed, 865 insertions, 79 deletions
diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown
new file mode 100644
index 00000000..21377b6c
--- /dev/null
+++ b/ru-ru/bash-ru.html.markdown
@@ -0,0 +1,284 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Darren Lin", "https://github.com/CogBear"]
+ - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
+ - ["Denis Arh", "https://github.com/darh"]
+ - ["akirahirose", "https://twitter.com/akirahirose"]
+ - ["Anton Strömkvist", "http://lutic.org/"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gregrory Kielian", "https://github.com/gskielian"]
+ - ["Etan Reisner", "https://github.com/deryni"]
+translators:
+ - ["Andrey Samsonov", "https://github.com/kryzhovnik"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+filename: LearnBash-ru.sh
+lang: ru-ru
+---
+
+Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X.
+Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell.
+
+[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/bin/bash
+# Первая строка скрипта - это shebang, который сообщает системе, как исполнять
+# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий.
+
+# Простой пример hello world:
+echo Hello world!
+
+# Отдельные команды начинаются с новой строки или разделяются точкой с запятой:
+echo 'Это первая строка'; echo 'Это вторая строка'
+
+# Вот так объявляется переменная:
+VARIABLE="Просто строка"
+
+# но не так:
+VARIABLE = "Просто строка"
+# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
+# и выдаст ошибку, потому что не сможет найти ее.
+
+# и не так:
+VARIABLE= 'Просто строка'
+# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
+# и выдаст ошибку, потому что не сможет найти такой команды
+# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
+# но только в контексте исполнения команды 'Просто строка').
+
+# Использование переменой:
+echo $VARIABLE
+echo "$VARIABLE"
+echo '$VARIABLE'
+# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
+# пишите её имя без $. А для получения значения переменной используйте $.
+# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
+
+# Подстановка строк в переменные
+echo ${VARIABLE/Просто/A}
+# Это выражение заменит первую встреченную подстроку "Просто" на "A"
+
+# Взять подстроку из переменной
+LENGTH=7
+echo ${VARIABLE:0:LENGTH}
+# Это выражение вернет только первые 7 символов переменной VARIABLE
+
+# Значение по умолчанию
+echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
+# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
+# ноль (FOO=0) вернет 0.
+# Заметьте, что в любом случае значение самой переменной FOO не изменится.
+
+# Встроенные переменные:
+# В bash есть полезные встроенные переменные, например
+echo "Последнее возвращенное значение: $?"
+echo "PID скрипта: $$"
+echo "Количество аргументов: $#"
+echo "Аргументы скрипта: $@"
+echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
+
+# Чтение аргументов из устройста ввода:
+echo "Как Вас зовут?"
+read NAME # Обратите внимание, что нам не нужно определять новую переменную
+echo Привет, $NAME!
+
+# У нас есть обычная структура if:
+# наберите 'man test' для получения подробной информации о форматах условия
+if [ $NAME -ne $USER ]
+then
+ echo "Имя не совпадает с именем пользователя"
+else
+ echo "Имя совпадает с именем пользователя"
+fi
+
+# Также есть условное исполнение
+echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
+echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
+
+# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
+if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
+then
+ echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
+fi
+
+if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
+then
+ echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
+fi
+
+# Выражения обозначаются таким форматом:
+echo $(( 10 + 5 ))
+
+# В отличие от других языков программирования, Bash - это командная оболочка,
+# а значит, работает в контексте текущей директории.
+# Вы можете просматривать файлы и директории в текущей директории командой ls:
+ls
+
+# У этой команды есть опции:
+ls -l # Показать каждый файл и директорию на отдельной строке
+
+# Результат предыдущей команды может быть направлен на вход следующей.
+# Команда grep фильтрует ввод по шаблону.
+# Так мы можем просмотреть только *.txt файлы в текущей директории:
+ls -l | grep "\.txt"
+
+# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
+# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
+# перезаписать hello.py следующим строками (до строки "EOF"):
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Запуск hello.py с разными вариантами перенаправления потоков
+# стандартных ввода, вывода и ошибок:
+python hello.py < "input.in"
+python hello.py > "output.out"
+python hello.py 2> "error.err"
+python hello.py > "output-and-error.log" 2>&1
+python hello.py > /dev/null 2>&1
+# Поток ошибок перезапишет файл, если этот файл существует,
+# поэтому, если вы хотите дописывать файл, используйте ">>":
+python hello.py >> "output.out" 2>> "error.err"
+
+# Переписать output.txt, дописать error.err и сосчитать строки:
+info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
+wc -l output.out error.err
+
+# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
+echo <(echo "#helloworld")
+
+# Перезаписать output.txt строкой "#helloworld":
+cat > output.out <(echo "#helloworld")
+echo "#helloworld" > output.out
+echo "#helloworld" | cat > output.out
+echo "#helloworld" | tee output.out >/dev/null
+
+# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
+rm -v output.out error.err output-and-error.log
+
+# Команды могут быть подставлены в строку с помощью $( ):
+# следующие команды выводят число файлов и директорий в текущей директории.
+echo "Здесь $(ls | wc -l) элементов."
+
+# То же самое можно сделать с использованием обратных кавычек,
+# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
+echo "Здесь `ls | wc -l` элементов."
+
+# В Bash есть структура case, которая похожа на switch в Java и C++:
+case "$VARIABLE" in
+ # Перечислите шаблоны для условий, которые хотите отловить
+ 0) echo "Тут ноль.";;
+ 1) echo "Тут один.";;
+ *) echo "Это не пустое значение.";;
+esac
+
+# Цикл for перебирает элементы переданные в аргументе:
+# Содержимое $VARIABLE будет напечатано три раза.
+for VARIABLE in {1..3}
+do
+ echo "$VARIABLE"
+done
+
+# Или с использованием "традиционного" синтаксиса цикла for:
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+done
+
+# Цикл for можно использовать для действий с файлами.
+# Запустим команду 'cat' для файлов file1 и file2
+for VARIABLE in file1 file2
+do
+ cat "$VARIABLE"
+done
+
+# ... или выводом из команд
+# Запустим cat для вывода из ls.
+for OUTPUT in $(ls)
+do
+ cat "$OUTPUT"
+done
+
+# Цикл while:
+while [ true ]
+do
+ echo "тело цикла здесь..."
+ break
+done
+
+# Вы можете определять функции
+# Определение:
+function foo ()
+{
+ echo "Аргументы работают также, как аргументы скрипта: $@"
+ echo "и: $1 $2..."
+ echo "Это функция"
+ return 0
+}
+
+# или просто
+bar ()
+{
+ echo "Другой способ определить функцию!"
+ return 0
+}
+
+# Вызов функции
+foo "Мое имя" $NAME
+
+# Есть много полезных команд, которые нужно знать:
+# напечатать последние 10 строк файла file.txt
+tail -n 10 file.txt
+# напечатать первые 10 строк файла file.txt
+head -n 10 file.txt
+# отсортировать строки file.txt
+sort file.txt
+# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
+uniq -d file.txt
+# напечатать только первую колонку перед символом ','
+cut -d ',' -f 1 file.txt
+# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
+sed -i 's/okay/great/g' file.txt
+# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
+# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
+grep "^foo.*bar$" file.txt
+# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
+grep -c "^foo.*bar$" file.txt
+# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
+fgrep "^foo.*bar$" file.txt
+
+# Читайте встроенную документацию оболочки Bash командой 'help':
+help
+help help
+help for
+help return
+help source
+help .
+
+# Читайте Bash man-документацию
+apropos bash
+man 1 bash
+man bash
+
+# Читайте документацию info (? для помощи)
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+
+# Читайте bash info документацию:
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
+```
diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown
index e7398c88..79844565 100644
--- a/ru-ru/javascript-ru.html.markdown
+++ b/ru-ru/javascript-ru.html.markdown
@@ -22,8 +22,8 @@ Google Chrome, становится все более популярной.
```js
// Си-подобные комментарии. Однострочные комментарии начинаются с двух символов слэш,
-/* а многострочные комментарии начинаются с звёздочка-слэш
- и заканчиваются символами слэш-звёздочка */
+/* а многострочные комментарии начинаются с последовательности слэш-звёздочка
+ и заканчиваются символами звёздочка-слэш */
// Инструкции могут заканчиваться точкой с запятой ;
doStuff();
diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown
index 3246de82..ddff2e5c 100644
--- a/ru-ru/objective-c-ru.html.markdown
+++ b/ru-ru/objective-c-ru.html.markdown
@@ -1,106 +1,171 @@
---
language: Objective-C
-filename: LearnObjectiveC.m
+filename: LearnObjectiveC-ru.m
contributors:
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
- ["Yannick Loriot", "https://github.com/YannickL"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
translators:
- ["Evlogy Sutormin", "http://evlogii.com"]
+ - ["Dmitry Bessonov", "https://github.com/TheDmitry"]
lang: ru-ru
---
-Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple,
-построенный на основе языка Си и парадигм Smalltalk.
-В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения.
+Objective-C — основной язык программирования, используемый корпорацией Apple
+для операционных систем OS X и iOS и их соответствующих фреймворках Cocoa и
+Cocoa Touch.
+Он является объектно-ориентированным языком программирования общего назначения,
+который добавляет обмен сообщениями в Smalltalk-стиле к языку программирования C.
```objective_c
-// Однострочный комментарий
+// Однострочные комментарии начинаются с //
/*
-Многострочный
-комментарий
+Так выглядят многострочные комментарии
*/
-// Импорт файлов фреймворка Foundation с помощью #import
+// Импорт заголовочных файлов фреймворка Foundation с помощью #import
+// Используйте <>, чтобы импортировать глобальные файлы (обычно фреймворки)
+// Используйте "", чтобы импортировать локальные файлы (из проекта)
#import <Foundation/Foundation.h>
#import "MyClass.h"
-// Точка входа в программу это функция main,
-// которая возвращает целый тип integer
+// Если вы включили модули для iOS >= 7.0 или OS X >= 10.9 проектов в
+// Xcode 5, вы можете импортировать фреймворки подобным образом:
+@import Foundation;
+
+// Точка входа в программу - это функция main,
+// которая возвращает целый тип
int main (int argc, const char * argv[])
{
- // Создание autorelease pool для управления памятью
+ // Создание autorelease pool для управления памятью в программе
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
+ // В место этого воспользуйтесь @autoreleasepool, если вы используете
+ // автоматический подсчет ссылок (ARC)
+ @autoreleasepool {
+
// Используйте NSLog для печати в консоль
- NSLog(@"Hello World!"); // Напечатает строку "Hello World!"
+ NSLog(@"Привет Мир!"); // Напечатает строку "Привет Мир!"
///////////////////////////////////////
// Типы и переменные
///////////////////////////////////////
- // Простое объявление
+ // Объявление простых типов
int myPrimitive1 = 1;
long myPrimitive2 = 234554664565;
+ // Объявление объектов
// Помещайте * в начало названия объекта для строго типизированного объявления
MyClass *myObject1 = nil; // Строгая типизация
id myObject2 = nil; // Слабая типизация
-
- NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
// %@ – это объект
- // 'description' это общий для всех объектов метод вывода данных
+ // 'description' - это общий для всех объектов метод вывода данных
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
// Строка
- NSString *worldString = @"World";
- NSLog(@"Hello %@!", worldString); // напечатает "Hello World!"
+ NSString *worldString = @"Мир";
+ NSLog(@"Привет %@!", worldString); // напечатает "Привет Мир!"
+ // NSMutableString - это изменяемая версия NSString-объекта
+ NSMutableString *mutableString = [NSMutableString stringWithString:@"Привет"];
+ [mutableString appendString:@" Мир!"];
+ NSLog(@"%@", mutableString); // напечатает => "Привет Мир!"
// Символьные литералы
NSNumber *theLetterZNumber = @'Z';
- char theLetterZ = [theLetterZNumber charValue];
+ char theLetterZ = [theLetterZNumber charValue]; // или 'Z'
NSLog(@"%c", theLetterZ);
- // Целочисленный литералы
+ // Целочисленные литералы
NSNumber *fortyTwoNumber = @42;
- int fortyTwo = [fortyTwoNumber intValue];
+ int fortyTwo = [fortyTwoNumber intValue]; // или '42'
NSLog(@"%i", fortyTwo);
// Беззнаковый целочисленный литерал
NSNumber *fortyTwoUnsignedNumber = @42U;
- unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // или 42
NSLog(@"%u", fortyTwoUnsigned);
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
- short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue]; // или 42
NSLog(@"%hi", fortyTwoShort);
+ NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41];
+ unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // или 41
+ NSLog(@"%u", fortyOneUnsigned);
+
NSNumber *fortyTwoLongNumber = @42L;
- long fortyTwoLong = [fortyTwoLongNumber longValue];
+ long fortyTwoLong = [fortyTwoLongNumber longValue]; // или 42
NSLog(@"%li", fortyTwoLong);
+
+ NSNumber *fiftyThreeLongNumber = @53L;
+ unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // или 53
+ NSLog(@"%lu", fiftyThreeUnsigned);
// Вещественный литерал
NSNumber *piFloatNumber = @3.141592654F;
- float piFloat = [piFloatNumber floatValue];
- NSLog(@"%f", piFloat);
+ float piFloat = [piFloatNumber floatValue]; // или 3.141592654f
+ NSLog(@"%f", piFloat); // напечатает 3.141592654
+ NSLog(@"%5.2f", piFloat); // напечатает " 3.14"
NSNumber *piDoubleNumber = @3.1415926535;
- double piDouble = [piDoubleNumber doubleValue];
+ double piDouble = [piDoubleNumber doubleValue]; // или 3.1415926535
NSLog(@"%f", piDouble);
-
+ NSLog(@"%4.2f", piDouble); // напечатает "3.14"
+
+ // NSDecimalNumber - это класс с фиксированной точкой, который является
+ // более точным, чем float или double
+ NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"];
+ NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"];
+ // NSDecimalNumber не способен использовать стандартные +, -, *, / операторы,
+ // поэтому он предоставляет свои собственные:
+ [oneDecNum decimalNumberByAdding:twoDecNum];
+ [oneDecNum decimalNumberBySubtracting:twoDecNum];
+ [oneDecNum decimalNumberByMultiplyingBy:twoDecNum];
+ [oneDecNum decimalNumberByDividingBy:twoDecNum];
+ NSLog(@"%@", oneDecNum); // напечатает "10.99", т.к. NSDecimalNumber - изменяемый
+
// BOOL (булевый) литерал
NSNumber *yesNumber = @YES;
NSNumber *noNumber = @NO;
-
+ // или
+ BOOL yesBool = YES;
+ BOOL noBool = NO;
+ NSLog(@"%i", yesBool); // напечатает 1
+
// Массив
+ // Может содержать различные типы данных, но должен быть объектом Objective-C
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
- NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
+ NSLog(@"Третье число = %@", thirdNumber); // Напечатает "Третье число = 3"
+ // NSMutableArray - это изменяемая версия NSArray, допускающая вам изменять
+ // элементы в массиве и расширять или сокращать массив.
+ // Удобный, но не эффективный как NSArray.
+ NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
+ [mutableArray addObject:@"Привет"];
+ [mutableArray addObject:@"Мир"];
+ [mutableArray removeObjectAtIndex:0];
+ NSLog(@"%@", [mutableArray objectAtIndex:0]); // напечатает "Мир"
// Словарь
- NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
- NSObject *valueObject = aDictionary[@"A Key"];
- NSLog(@"Object = %@", valueObject); // Напечатает "Object = (null)"
-
+ NSDictionary *aDictionary = @{ @"ключ1" : @"значение1", @"ключ2" : @"значение2" };
+ NSObject *valueObject = aDictionary[@"Ключ"];
+ NSLog(@"Объект = %@", valueObject); // Напечатает "Объект = (null)"
+ // NSMutableDictionary тоже доступен, как изменяемый словарь
+ NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+ [mutableDictionary setObject:@"значение1" forKey:@"ключ1"];
+ [mutableDictionary setObject:@"значение2" forKey:@"ключ2"];
+ [mutableDictionary removeObjectForKey:@"ключ1"];
+
+ // Множество
+ NSSet *set = [NSSet setWithObjects:@"Привет", @"Привет", @"Мир", nil];
+ NSLog(@"%@", set); // напечатает {(Hello, World)} (порядок может отличаться)
+ // NSMutableSet тоже доступен, как изменяемое множество
+ NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2];
+ [mutableSet addObject:@"Привет"];
+ [mutableSet addObject:@"Привет"];
+ NSLog(@"%@", mutableSet); // напечатает => {(Привет)}
+
///////////////////////////////////////
// Операторы
///////////////////////////////////////
@@ -124,13 +189,13 @@ int main (int argc, const char * argv[])
// Условный оператор
if (NO)
{
- NSLog(@"I am never run");
+ NSLog(@"Я никогда не выполнюсь");
} else if (0)
{
- NSLog(@"I am also never run");
+ NSLog(@"Я тоже никогда не выполнюсь");
} else
{
- NSLog(@"I print");
+ NSLog(@"Я напечатаюсь");
}
// Ветвление с множественным выбором
@@ -138,15 +203,15 @@ int main (int argc, const char * argv[])
{
case 0:
{
- NSLog(@"I am never run");
+ NSLog(@"Я никогда не выполнюсь");
} break;
case 1:
{
- NSLog(@"I am also never run");
+ NSLog(@"Я тоже никогда не выполнюсь");
} break;
default:
{
- NSLog(@"I print");
+ NSLog(@"Я напечатаюсь");
} break;
}
@@ -170,7 +235,7 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
- // // Цикл просмотра
+ // Цикл просмотра
NSArray *values = @[@0, @1, @2, @3];
for (NSNumber *value in values)
{
@@ -180,20 +245,32 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
+ // Цикл for для объектов. Может использоваться с любым объектом Objective-C
+ for (id item in values) {
+ NSLog(@"%@,", item);
+ } // напечатает => "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
// Обработка исключений
@try
{
// Ваше исключение здесь
@throw [NSException exceptionWithName:@"FileNotFoundException"
- reason:@"File Not Found on System" userInfo:nil];
+ reason:@"Файл не найден в системе" userInfo:nil];
} @catch (NSException * e)
{
- NSLog(@"Exception: %@", e);
+ NSLog(@"Исключение: %@", e);
} @finally
{
- NSLog(@"Finally");
- } // => напечатает "Exception: File Not Found on System"
- // "Finally"
+ NSLog(@"В конце отводится время для очистки.");
+ } // => напечатает "Исключение: Файл не найден в системе"
+ // "В конце отводится время для очистки."
+
+ // NSError - это полезные объекты для аргументов функции, чтобы заполнить их
+ // пользовательскими ошибками.
+ NSError *error = [NSError errorWithDomain:@"Неправильный эл. адрес." code:4 userInfo:nil];
///////////////////////////////////////
// Объекты
@@ -203,13 +280,16 @@ int main (int argc, const char * argv[])
// Объект не является полнофункциональным пока обе части не выполнятся.
MyClass *myObject = [[MyClass alloc] init];
- // В Objective-C можель ООП базируется на передаче сообщений.
+ // В Objective-C модель ООП базируется на передаче сообщений.
// В Objective-C Вы не просто вызваете метод; вы посылаете сообщение.
- [myObject instanceMethodWithParameter:@"Steve Jobs"];
+ [myObject instanceMethodWithParameter:@"Стив Джобс"];
// Очищайте память, перед завершением работы программы.
[pool drain];
+ // Конец @autoreleasepool
+ }
+
// Конец программы.
return 0;
}
@@ -222,63 +302,144 @@ int main (int argc, const char * argv[])
// Синтаксис объявления:
// @interface ИмяКласса : ИмяКлассаРодителя <ИмплементируемыеПротоколы>
// {
-// Объявление переменных;
+// тип имя; <= Объявление переменных;
// }
+// @property тип имя; <= объявление свойств
// -/+ (тип) Объявление метода(ов).
// @end
-
-
-@interface MyClass : NSObject <MyProtocol>
+@interface MyClass : NSObject <MyProtocol> // NSObject - это базовый класс в Objective-C.
{
- int count;
- id data;
+ // Объявления экземпляров переменных (может существовать в файлах интерфейса или реализвации)
+ int count; // По умолчанию защищенный доступ.
+ @private id data; // Приватный доступ (Намного удобнее объявлять в файле реализации)
NSString *name;
}
-// При объявлении свойств сразу генерируются геттер и сеттер
-@property int count;
-@property (copy) NSString *name; // Скопировать объект в ходе присвоения.
-@property (readonly) id data; // Генерация только геттера
+// Удобное обозначение для переменных с открытым (public) доступом
+// автоматически генерируется сеттер-метод
+// По умолчанию название сеттер-метода начинается с 'set' с последующим именем
+// переменной из @property
+@property int propInt; // Имя сеттер-метода = 'setPropInt'
+@property (copy) id copyId; // (copy) => Скопировать объект в ходе присвоения.
+// (readonly) => Не позволяет установить значение вне @interface
+@property (readonly) NSString *roString; // Используйте @synthesize
+ // в @implementation, чтобы создать аксессор
+// Вы можете настроить геттер и сеттер имена вместо используемого 'set'-имени по умолчанию:
+@property (getter=lengthGet, setter=lengthSet:) int length;
// Методы
-+/- (return type)methodSignature:(Parameter Type *)parameterName;
++/- (возвращаемый тип)сигнатураМетода:(Параметр типа *)имяПараметра;
// + для методов класса
+ (NSString *)classMethod;
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight;
-// - для метода объекта
+// - для методов объекта
- (NSString *)instanceMethodWithParameter:(NSString *)string;
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
-@end
+// Методы-конструктор с аргументом:
+- (id)initWithDistance:(int)defaultDistance;
+// В Objective-C имена методов очень описательные. Всегда имена методов соответствуют своим аргументам
+
+@end // Устанавливает конец интерфейса (interface)
+
+
+// Чтобы обратиться к открытым (public) переменным из файла реализации, @property генерирует сеттер-метод
+// автоматически. Название метода - это 'set' с последующим именем переменной из @property:
+MyClass *myClass = [[MyClass alloc] init]; // создает экземпляр объекта класса MyClass
+[myClass setCount:10];
+NSLog(@"%d", [myClass count]); // напечатает => 10
+// Или используйте свой геттер и сеттер методы, которые определены в @interface:
+[myClass lengthSet:32];
+NSLog(@"%i", [myClass lengthGet]); // напечатает => 32
+// Для удобства вы можете использовать точечную нотацию,
+// чтобы установить и получить доступ к переменным объекта:
+myClass.count = 45;
+NSLog(@"%i", myClass.count); // напечатает => 45
+
+// Вызов методов класса:
+NSString *classMethodString = [MyClass classMethod];
+MyClass *classFromName = [MyClass myClassFromName:@"Привет"];
+
+// Вызов методов экземпляра:
+MyClass *myClass = [[MyClass alloc] init]; // Создает экземпляр объекта MyClass
+NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Привет"];
+
+// Селекторы
+// Это способ динамически представить методы. Используйте для вызова методов класса, передайте методы
+// через функции, чтобы сказать другим классам, что они должны вызвать их и сохранить методы
+// как переменные
+// SEL - это тип данных. @selector() вернет селектор из предоставленного имени метода
+// methodAParameterAsString:andAParameterAsNumber: - это название метода в MyClass
+SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
+if ([myClass respondsToSelector:selectorVar]) { // Проверяет содержит ли класс метод
+ // Необходимо установить все аргументы метода в один объект, что отправить его в performSelector-функцию
+ NSArray *arguments = [NSArray arrayWithObjects:@"Привет", @4, nil];
+ [myClass performSelector:selectorVar withObject:arguments]; // Вызывает метод
+} else {
+ // NSStringFromSelector() вернет NSString название метода полученного селектором
+ NSLog(@"MyClass не содержит метод: %@", NSStringFromSelector(selectedVar));
+}
// Имплементируйте методы в файле МойКласс.m:
+@implementation MyClass {
+ long distance; // Переменная экземпляра с закрытым (private) доступом
+ NSNumber height;
+}
-@implementation MyClass
+// To access a public variable from the interface file, use '_' followed by variable name:
+_count = 5; // References "int count" from MyClass interface
+// Access variables defined in implementation file:
+distance = 18; // References "long distance" from MyClass implementation
+// To use @property variable in implementation, use @synthesize to create accessor variable:
+@synthesize roString = _roString; // _roString available now in @implementation
+
+// Called before calling any class methods or instantiating any objects
++ (void)initialize
+{
+ if (self == [MyClass class]) {
+ distance = 0;
+ }
+}
// Вызывается при высвобождении памяти под объектом
- (void)dealloc
{
+ [height release]; // Если не используется ARC, убедитесь в освобождении переменных объекта класса
+ [super dealloc]; // and call parent class dealloc
}
-// Конструкторы – это способ осздания объектов класса.
-// Это обычный конструктор вызываемый при создании объекта клсааа.
+// Конструкторы – это способ создания объектов класса.
+// Это конструктор по умолчанию, который вызывается, когда объект инициализируется.
- (id)init
{
- if ((self = [super init]))
+ if ((self = [super init])) // 'super' используется для того, чтобы обратиться к методам родительского класса
{
- self.count = 1;
+ self.count = 1; // 'self' используется для вызова самого себя
}
return self;
}
+// Можно создать конструкторы, которые содержат аргументы:
+- (id)initWithDistance:(int)defaultDistance
+{
+ distance = defaultDistance;
+ return self;
+}
+ (NSString *)classMethod
{
return [[self alloc] init];
}
++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight
+{
+ height = defaultHeight;
+ return [[self alloc] init];
+}
+
- (NSString *)instanceMethodWithParameter:(NSString *)string
{
- return @"New string";
+ return @"Новая строка";
}
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
@@ -286,23 +447,364 @@ int main (int argc, const char * argv[])
return @42;
}
+// Objective-C не содержит объявление приватных методов, но вы можете имитировать их.
+// Чтобы сымитировать приватный метод, создайте метод в @implementation, но не в @interface.
+- (NSNumber *)secretPrivateMethod {
+ return @72;
+}
+[self secretPrivateMethod]; // Вызывает приватный метод
+
// Методы объявленные в МyProtocol (см. далее)
- (void)myProtocolMethod
{
- // имплементация
+ // операторы
}
+@end // Устанавливает конец реализации (implementation)
+
+///////////////////////////////////////
+// Категории
+///////////////////////////////////////
+// Категория - это группа методов предназначенные для того, чтобы расширить класс. Они позволяют вам добавить новые методы
+// к существующему классу для организационных целей. Это не стоит путать с подклассами.
+// Подклассы предназначены для ИЗМЕНЕНИЯ функциональности объекта пока как категории ДОБАВЛЯЮТ
+// функциональность в объект.
+// Категории позволяют вам:
+// -- Добавлять методы в существующий класс для организационных целей.
+// -- Допускает вам расширять объекты Objective-C классов (напр.: NSString) добавить ваши собственные методы.
+// -- Добавляет возможность создать защищенные и закрытые методы классов.
+// ПРИМЕЧАНИЕ: Не переопределяйте методы базового класса в категории даже если у вас есть возможность это сделать
+// to. Переопределение методов может привести к ошибкам компиляции позднее между различными категориями и это
+// нарушает цель категорий, чтобы добавлять только функциональность. Вместо этого подклассы переопределяют методы.
+
+// Здесь простой базовый класс Car.
+@interface Car : NSObject
+
+@property NSString *make;
+@property NSString *color;
+
+- (void)turnOn;
+- (void)accelerate;
+
@end
-/*
- * Протокол объявляет методы которые должны быть имплементированы
- * Протокол не является классом. Он просто определяет интерфейс,
- * который должен быть имплементирован.
- */
+// И реализация базового класса Car:
+#import "Car.h"
+
+@implementation Car
+
+@synthesize make = _make;
+@synthesize color = _color;
+
+- (void)turnOn {
+ NSLog(@"Машина заведена.");
+}
+- (void)accelerate {
+ NSLog(@"Ускорение.");
+}
-@protocol MyProtocol
- - (void)myProtocolMethod;
@end
+
+// Теперь, если мы хотели создать грузовой объект, мы должны вместо создания подкласса класса Car, как это будет
+// изменять функциональность Car чтобы вести себя подобно грузовику. Но давайте посмотрим, если мы хотим только добавить
+// функциональность в существующий Car. Хороший пример должен быть чистить автомобиль. Итак мы создадим
+// категорию для добавления его очистительных методов:
+// @interface ИмяФайла: Car+Clean.h (ИмяБазовогоКласса+ИмяКатегории.h)
+#import "Car.h" // Убедитесь в том, что базовый класс импортирован для расширения.
+
+@interface Car (Clean) // Имя категории внутри (), следующие после имени базового класса.
+
+- (void)washWindows; // Названия новых методов, которые мы добавляем в наш объект Car.
+- (void)wax;
+
+@end
+
+// @implementation имя файла: Car+Clean.m (ИмяБазовогоКласса+ИмяКатегории.m)
+#import "Car+Clean.h" // Импортируйте Очистку файл @interface категории.
+
+@implementation Car (Clean)
+
+- (void)washWindows {
+ NSLog(@"Окна промыли.");
+}
+- (void)wax {
+ NSLog(@"Воском натерли.");
+}
+
+@end
+
+// Любой экземпляр объекта Car имеет возможность воспользоваться категорией. Все, что нужно сделать, это импортировать ее:
+#import "Car+Clean.h" // Импортировать как множество различных категорий, как вы хотите использовать.
+#import "Car.h" // Кроме того, необходимо импортировать базовый класс для использования его оригинальные функциональные возможности.
+
+int main (int argc, const char * argv[]) {
+ @autoreleasepool {
+ Car *mustang = [[Car alloc] init];
+ mustang.color = @"Красный";
+ mustang.make = @"Форд";
+
+ [mustang turnOn]; // Используйте методы из базового класса Car.
+ [mustang washWindows]; // Используйте методы категории Clean из класса Car.
+ }
+ return 0;
+}
+
+// Objective-C не поддерживает объявление защищенных методов, но вы можете имитировать их.
+// Создайте категорию, содержащую все защищенные методы, затем импортируйте ее только в
+// @implementation-файле класса, относящегося к классу Car:
+@interface Car (Protected) // Наименование категории с помощью 'Protected'
+// дает знать, что методы защищенные.
+
+- (void)lockCar; // Здесь перечисляются методы, которые должны быть созданы
+// только с помощью объектов класса Car.
+
+@end
+// Чтобы воспользоваться защищенными методами, импортируйте категорию, затем реализуйте методы:
+#import "Car+Protected.h" // Запомните, делайте импорт только в файле с @implementation.
+
+@implementation Car
+
+- (void)lockCar {
+ NSLog(@"Машина закрыта."); // Экземпляры класса Car не могут использовать
+// метод lockCar, потому что он объявлен не в @interface.
+}
+
+@end
+
+///////////////////////////////////////
+// Расширения
+///////////////////////////////////////
+// Расширения позволяют вам переопределять атрибуты свойств и методов
+// с открытым доступом в @interface.
+// @interface имя файла: Shape.h
+@interface Shape : NSObject // Расширение базового класса Shape переопределяет
+ // свои поля ниже.
+
+@property (readonly) NSNumber *numOfSides;
+
+- (int)getNumOfSides;
+
+@end
+// Вы можете переопределить numOfSides-переменную или getNumOfSides-метод
+// Внесение изменений с помощью расширения делается следующим образом:
+// @implementation имя файла: Shape.m
+#import "Shape.h"
+// Расширения "живут" в том же файле, где и @implementation класса.
+@interface Shape () // После имени базового класса скобки () объявляют расширение.
+
+@property (copy) NSNumber *numOfSides; // Делает numOfSides-свойство
+ // копирующим (copy) вместо свойства только для чтения (readonly).
+-(NSNumber)getNumOfSides; // Изменяет метод getNumOfSides так,
+ // чтобы он возвращал объект NSNumber вместо типа int.
+-(void)privateMethod; // Вы также можете создать новый закрытый метод
+ // внутри расширения.
+
+@end
+// Главный @implementation:
+@implementation Shape
+
+@synthesize numOfSides = _numOfSides;
+
+-(NSNumber)getNumOfSides { // Все операторы внутри расширения
+ // должны быть в @implementation.
+ return _numOfSides;
+}
+-(void)privateMethod {
+ NSLog(@"Закрытый метод созданный с помощью расширения.");
+ NSLog(@"Экземпляр Shape не может вызвать этот метод.");
+}
+
+@end
+
+///////////////////////////////////////
+// Протоколы
+///////////////////////////////////////
+// Протокол объявляет методы, которые могут быть реализованы с помощью
+// любого класса. Протоколы сами по себе не являются классами. Они просто
+// определяют интерфейс, который должен быть реализован другими объектами.
+// @protocol имя файла: "CarUtilities.h"
+@protocol CarUtilities <NSObject> // <NSObject> => Имя другого протокола,
+// который включен в этот протокол.
+ @property BOOL engineOn; // Адаптирующий класс должен определить
+// все @synthesize для @property и
+ - (void)turnOnEngine; // определить все методы.
+@end
+// Ниже пример класса, реализующий протокол.
+#import "CarUtilities.h" // Импорт файла с @protocol.
+
+@interface Car : NSObject <CarUtilities> // Внутри <> имя протокола
+// Здесь вам не нужно указывать @property или имена методов для CarUtilities.
+// Они нужны только для @implementation.
+- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // Вы также можете
+// указать тип протоколов.
+@end
+// В @implementation нужно реализовать все @property и методы для протокола.
+@implementation Car : NSObject <CarUtilities>
+
+@synthesize engineOn = _engineOn; // Создайте @synthesize-оператор
+// для "@property engineOn".
+
+- (void)turnOnEngine { // Реализуйте turnOnEngine как вам угодно. Протоколы
+// не определят,
+ _engineOn = YES; // как вам реализовать метод, он только требует,
+// чтобы вы реализовали его.
+}
+// Вы можете использовать протокол как данные, если вы знаете, что он реализует
+// методы и переменные.
+- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
+ [objectOfSomeKind engineOn]; // У вас есть доступ к переменным объекта
+ [objectOfSomeKind turnOnEngine]; // и методам.
+ [objectOfSomeKind engineOn]; // Может или не может быть значение YES. Класс
+// реализует как нужно.
+}
+
+@end
+// Экземпляры класса Car сейчас имеют доступ к протоколу.
+Car *carInstance = [[Car alloc] init];
+[carInstance setEngineOn:NO];
+[carInstance turnOnEngine];
+if ([carInstance engineOn]) {
+ NSLog(@"Двигатель запущен."); // напечатает => "Двигатель запущен."
+}
+// Убедитись в том, что объект типа 'id' реализует протокол перед вызовом методов протокола:
+if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"Не работает, т.к. класс MyClass не реализует протокол CarUtilities.");
+} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
+ NSLog(@"Работает как класс Car, который реализует протокол CarUtilities.");
+}
+// Категории тоже могут реализовать протоколы:
+// @interface Car (CarCategory) <CarUtilities>
+// Вы можете реализовать много протоколов:
+// @interface Car : NSObject <CarUtilities, CarCleaning>
+// ЗАМЕЧАНИЕ: Если два или более протоколов полагаются друг на друга,
+// убедитесь, что они ранее объявлены:
+#import "Brother.h"
+
+@protocol Brother; // Оператор раннего объявления. Без него компилятор
+// выдаст ошибку.
+
+@protocol Sister <NSObject>
+
+- (void)beNiceToBrother:(id <Brother>)brother;
+
+@end
+
+// Рассмотрите проблему, где протокол Sister полагается на протокол Brother,
+// а Brother полагается на Sister.
+#import "Sister.h"
+
+@protocol Sister; // Эти строки предотвращают рекурсию, решая этим проблему.
+
+@protocol Brother <NSObject>
+
+- (void)beNiceToSister:(id <Sister>)sister;
+
+@end
+
+
+///////////////////////////////////////
+// Блоки
+///////////////////////////////////////
+// Блоки - это операторы кода, наподобие функции, которую возможно использовать
+// как данные.
+// Ниже простой блок с целочисленным аргументом, и возвращает аргумент плюс 4.
+int (^addUp)(int n); // Объявите переменную, чтобы сохранить блок.
+void (^noParameterBlockVar)(void); // Пример объявления блока-переменной
+// без аргументов.
+// Блоки имею доступ к переменным в той же области видимости. Но переменные
+// будут только для чтения, и значения переданных в блок станут значением
+// переменной, когда блок создастся.
+int outsideVar = 17; // Если мы редактируем outsideVar после объявления addUp,
+// outsideVar остается равным 17.
+__block long mutableVar = 3; // __block делают переменные перезаписываемыми
+// в блоках, в отличие от outsideVar.
+addUp = ^(int n) { // Удалите (int n) в блоке, чтобы не принимать
+// какие-либо параметры.
+ NSLog(@"Вы можете иметь столько строк в блоке, сколько вы хотели.");
+ NSSet *blockSet; // Также вы можете объявить локальные переменные.
+ mutableVar = 32; // Присвоить новое значение к __block-переменной.
+ return n + outsideVar; // Необязательный оператор возврата.
+}
+int addUp = add(10 + 16); // Вызывает блок кода с аргументами.
+// Блоки часто используются как аргументы функции, чтобы позже их вызвать, или
+// как функции обратного вызова (callbacks).
+@implementation BlockExample : NSObject
+
+- (void)runBlock:(void (^)(NSString))block {
+ NSLog(@"В аргументе блок ничего не возвращает и принимает NSString-объект.");
+ block(@"Аргумент передан блоку на исполнение."); // Вызов блока.
+}
+
+@end
+
+
+///////////////////////////////////////
+// Управление памятью
+///////////////////////////////////////
+/*
+Для каждого объекта, используемого в приложении, должна быть выделена память
+для таких объектов. Когда приложение прекращает использование объекта, память
+должна быть освобождена, чтобы гарантировать эффективность приложения.
+Objective-C не использует сборщик мусора, а вместо этого применяет подсчет ссылок.
+Пока существует по крайней мере одна ссылка на объект (также называется
+"владение" объектом), то объект будет доступен к использованию (еще известно
+как "право владения").
+
+Когда экземпляр владеет объектом, его ссылка увеличивается на один. Когда
+объекта освобождается, счетчик ссылки уменьшается на один. Когда счетчик ссылки
+равен нулю, объект удаляется из памяти.
+
+Над всеми объектами взаимодействуют, следуя паттерну:
+(1) создание объекта, (2) использование объекта, (3) затем освобождение объекта из памяти.
+*/
+
+MyClass *classVar = [MyClass alloc]; // 'alloc' устанавливает счетчик ссылки
+// объекта classVar на 1 и возвращает указатель на объект.
+[classVar release]; // Уменьшает счетчик ссылки объекта classVar
+// 'retain' заявляет право собственности на существующий экземпляр объекта
+// и увеличивает счетчик ссылки. Затем вернет указатель на объект.
+MyClass *newVar = [classVar retain]; // Если classVar освободится, объект
+// останется в памяти, потому что newVar - владелец
+[classVar autorelease]; // Удалит право на владение объектом
+// в конце @autoreleasepool блока. Вернет указатель на объект.
+
+// @property может использовать 'retain' и 'assign' тоже для маленького
+// удобного определения
+@property (retain) MyClass *instance; // Освободит старое значение и сохранит
+// одно новое (строгая ссылка)
+@property (assign) NSSet *set; // Укажет на новое значение
+// без сохранения/освобождения старого значения (слабая ссылка)
+
+// Автоматический подсчет ссылок (ARC)
+// Управление памятью может быть трудным, поэтому в Xcode 4.2 и iOS 4 введен
+// автоматический подсчет ссылок (ARC).
+// ARC - это особенность компилятора, который помещает "retain", "release"
+// и "autorelease" автоматически за вас тогда, когда используется ARC,
+// вам не нужно больше обращаться к "retain", "relase" или "autorelease"
+MyClass *arcMyClass = [[MyClass alloc] init];
+// ... код, использующий объект arcMyClass
+// Без ARC, вам нужно было бы вызвать: [arcMyClass release] после того, как вы
+// завершите работу с объектом arcMyClass. Но с ARC,
+// теперь этого не нужно делать. Он будет помещать release-вызов за вас
+
+// Что касается 'assign' и 'retain' @property атрибутов, в ARC вы должны
+// использовать 'weak' и 'strong'
+@property (weak) MyClass *weakVar; // 'weak' не принимает право на владение
+// объектом. Если исходный счетчик ссылки экземпляра обнуляется,
+// weakVar-свойство автоматически примет значение nil,
+// во избежание падения приложения
+@property (strong) MyClass *strongVar; // 'strong' принимает право на владение
+// объектом. Гарантирует, что объект останится в памяти для использования
+
+// Для обычных переменных (не объявленных с помощью @property), используйте
+// следующий способ:
+__strong NSString *strongString; // По умолчанию. Переменная сохраняется в памяти,
+// пока она не покинет область видимости
+__weak NSSet *weakSet; // Слабая ссылка на существующий объект. Когда существующий
+// объект освобождается, weakSet принимает nil
+__unsafe_unretained NSArray *unsafeArray; // Похож на __weak, но unsafeArray
+// не принимает nil, когда существующий объект освобождается
+
```
## На почитать
diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown
index fd95c876..2a7b3f7b 100644
--- a/ru-ru/python3-ru.html.markdown
+++ b/ru-ru/python3-ru.html.markdown
@@ -593,7 +593,7 @@ def double_numbers(iterable):
range_ = range(1, 900000000)
# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(xrange_):
+for i in double_numbers(range_):
print(i)
if i >= 30:
break