Нельзя просто так взять и обновить UI, когда пришел ответ с сервера
Нельзя просто так взять и обновить UI, когда пришел ответ с сервера
Программисты с опытом ObjC могут посмеяться над этой «ловушкой», потому что она должна быть общеизвестна: методы, связанные с UI, безопасно дергать только из главного потока. Иначе — непредсказуемость и баги, толкающие в тотальный ступор. Но это наставление почему-то проходило мимо меня, пока я, наконец, не столкнулся с жуткими багами.
Пример «проблемного» кода:
func fetchFromServer() { let url = NSURL(string:urlString)! NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { data, response, error in if (error != nil) { ... } else { self.onSuccess(data) } })!.resume() } func onSuccess(data) { updateUI() }
Обратите внимание на блок completionHandler — все это будет исполняться вне главного потока! Тем, кто еще не столкнулся с последствиями, советую не экспериментировать, а просто не забыть обставить updateUI следующим образом:
func onSuccess(data) { dispatch_sync(dispatch_get_main_queue(), { updateUI() }) }
DispatchQueue.main.sync(execute: { let item = arRecords[indexPath.row] as TaskModel detailVC.setDataSource(item: item) })
iOS: Модальные окна
закрытие модального окна
dismiss(animation:true,nil)
чтобы окно-всплывашка была поверх текущего окна
- выставляем цвет у View backgound: Clear Color
- у ViewController указыаем presentation: Over Current Context
let frame:CGRect = CGRect(x: 50, y: 30, width: 200, height: 300) self.view.frame = frame
ставим рамку и цвет рамки у PopUp окна
override func viewDidLayoutSubviews() { ... self.view.layer.borderWidth = 1 self.view.layer.borderColor = UIColor.black.cgColor }
получаем контроллер из Storyboard программно
let SpecialViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SpecialViewController") as! SpecialViewController
SECTION_CODE_PATH
в urlrewrite.php
array( "CONDITION" => '#^/catalog/([/\-_.a-zA-Z0-9]+)/(.*?)\.html#', "RULE" => "SECTION_PATH=$1&ELEMENT_CODE=$2", "ID" => "bitrix:catalog.section", "PATH" => "/catalog/index.php", ), array( "CONDITION" => '#^/catalog/([/\-_.a-zA-Z0-9]+)/#', "RULE" => "SECTION_PATH=$1&$2", "ID" => "bitrix:catalog.section", "PATH" => "/catalog/index.php", ), array( "CONDITION" => "#^/catalog/#", "RULE" => "", "ID" => "bitrix:catalog.section", "PATH" => "/catalog/index.php", ),
date_default_timezone_set
Устанновить временную зону Москва
date_default_timezone_set('Europe/Moscow');
Bitrix записать дату в d7
$arItem["TIMESTAMP_X"]= new \Bitrix\Main\Type\Date(date("d.m.Y"));
Bitrix: Консольные скрипты
// эту соль по вкусу #set_time_limit(0); #ini_set('output_buffering','off'); #date_default_timezone_set('Europe/Moscow'); // это мы проверяем что мы запускаемся тока из консольки if (php_sapi_name()!="cli") die(); $_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../../"); require_once ($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); //у битрикса тройной буфер, поэтому 3 буфера мы и очищаем-отключаем. ob_end_clean(); ob_end_clean(); ob_end_clean();
document ready native JS
$(document).ready(function(){ console.info("document is ready"); });
Нативный Аналог
document.addEventListener("DOMContentLoaded", function(){ console.info("document is ready"); });
убрать вкладку «реклама»
$eventManager = \Bitrix\Main\EventManager::getInstance(); $eventManager->unRegisterEventHandler("main", "OnAdminIBlockElementEdit", "seo", "\\Bitrix\\Seo\\AdvTabEngine", "eventHandler");
sshfs
Памятка bash скрипта монтирующего каталог проекта
#!/bin/bash sshfs kirill@adeveloper.ru:/var/www/ /home/kirill/projects/adeveloper.ru -o uid=1000,gid=1000
выкачать сайт
выкачать сайт со всеми страницами и ссылкми
wget -r -k -l 1 -p -E -nc http://yandex.ru
Разница между Class и Struct на примере
Class vs Struct
class Target { var location = "" } //struct Target { // var location = "" //} class Pilot { var target: Target = Target() } class Script { func run() { let luke = Pilot() let wedge = Pilot() luke.target.location = "Star Deth" // Люку приказывают лететь к звезде смерти wedge.target = luke.target // Вейджу приказано лететь туда же print("Luke target: \(luke.target.location)") print("Wedge target: \(wedge.target.location)\n\n") wedge.target.location = "Return to base" // Вейджу приказано вернуться на базу print("Luke target: \(luke.target.location)") print("Wedge target: \(wedge.target.location)\n\n") let result = luke.target.location.compare("Star Deth") if result.rawValue == 0 { print("Rebel wins ") } else { print("Empire wins ") } } }
putty: export session list
regedit /e "%userprofile%\Desktop\putty-sessions.reg" HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions
Docker: Памятка
docker images docker start <имя контейнера| hash контейнера> docker run -tid -v ~/proj_dir/:/var/www/ -p 8080:80 project/work bash /root/start docker ps docker exec -ti <имя контейнера| hash контейнера> ls -la docker stop <имя контейнера| hash контейнера>
php rgb2hex
protected function rgb2hex($r,$g,$b) { return '#' . sprintf('%02x', $r) . sprintf('%02x', $g) . sprintf('%02x', $b); }
Bitrix: Белый экран смерти
WSOD — White Screen Of Death
Бывает что некорректно написанный скрипт под Битриксом падает белым пустым экраном смерти и никакого намёка на место падения.
В таких случаях надо переопределить PHP Shutdown Function следующим образом,
код можно вставить в init.php
function ShutdownHandler() { if(@is_array($error = @error_get_last())) { return(@call_user_func_array('ErrorHandler', $error)); }; return(TRUE); }; register_shutdown_function('ShutdownHandler'); // ---------------------------------------------------------------------------------------------------- // - Error Handler // ---------------------------------------------------------------------------------------------------- function ErrorHandler($type, $message, $file, $line) { $_ERRORS = Array( 0x0001 => 'E_ERROR', 0x0002 => 'E_WARNING', 0x0004 => 'E_PARSE', 0x0008 => 'E_NOTICE', 0x0010 => 'E_CORE_ERROR', 0x0020 => 'E_CORE_WARNING', 0x0040 => 'E_COMPILE_ERROR', 0x0080 => 'E_COMPILE_WARNING', 0x0100 => 'E_USER_ERROR', 0x0200 => 'E_USER_WARNING', 0x0400 => 'E_USER_NOTICE', 0x0800 => 'E_STRICT', 0x1000 => 'E_RECOVERABLE_ERROR', 0x2000 => 'E_DEPRECATED', 0x4000 => 'E_USER_DEPRECATED' ); if(!@is_string($name = @array_search($type, @array_flip($_ERRORS)))) { $name = 'E_UNKNOWN'; }; return(print(@sprintf("%s Error in file %s at line %d: %s\n", $name, @basename($file), $line, $message))); }; $old_error_handler = set_error_handler("ErrorHandler");
и так мы узнаем где и что упало
isArray
class Utils { static isArray(value) { return value && typeof value === 'object' && value.constructor === Array; } }
Javascript: Наследование
function extend(Child, Parent) { var F = function() { } F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.superclass = Parent.prototype; } function Box(){ console.log("constructor"); } Box.prototype.show = function(){ console.log("show();"); }; function IconBox(){ //IconBox.superclass.constructor(); console.log("constructor IconBox"); }; //extend(IconBox,Box); //IconBox.prototype = Object.create(Box.prototype); IconBox.prototype = new Box(); var box = new IconBox(); box.show();
LocalRedirect Пользователей
Перенаправление групп пользователей по домашним директориям
somewhere.php
class UserGroupsRedirect{ /** * @param $fields * После авторизаци перебрасываем пользователя в назначенную его группе директорию */ function OnAfterUserLoginHandler(&$fields) { global $USER; \Bitrix\Main\Diag\Debug::dumpToFile($USER->GetUserGroupArray()); if (!ADMIN_SECTION) { if ((!empty($fields['USER_ID'])) && (in_array('5',$USER->GetUserGroupArray()))){ LocalRedirect("/"); } if ((!empty($fields['USER_ID'])) && (in_array('6',$USER->GetUserGroupArray()))){ LocalRedirect("/vip/"); } if ((!empty($fields['USER_ID'])) && (in_array('8',$USER->GetUserGroupArray()))){ LocalRedirect("/user/profile/"); } } } }
init.php
// обработкчики событий use Bitrix\Main\EventManager; $handler = EventManager::getInstance()->addEventHandler( "main", "OnAfterUserLogin", array( "UserGroupsRedirect", "OnAfterUserLoginHandler" ) );
JavaScript: Синтаксис классов
Синтаксис
class ClassName{ constructor(){ this.item = 1; this.name = "Name of Something"; this.arParams = []; this.params = {}; } methodName(){ return 1; } };
Применение
var arItems = []; arItems.push( new ClassName()); // добавляем к массиву уже новый экземпляр класса
