Как определить, поддерживает ли устройство на iOS эффект blur (размытие)?

Вариант 1. Требуется определить поддерживает ли устройство blur программно.
Решение:

http://stackoverflow.com/questions/19412094/how-can-i-detect-if-an-ios-device-supports-the-blur-effect

Код:

@interface UIDevice (Additions)

@property (readonly) NSString *platform;
@property (readonly) BOOL canBlur;

@end


@implementation UIDevice (Additions)

- (NSString *)platform {
    int mib[] = { CTL_HW, HW_MACHINE };
    size_t len = 0;
    sysctl(mib, 2, NULL, &len, NULL, 0);
    char *machine = malloc(len);
    sysctl(mib, 2, machine, &len, NULL, 0);
    NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
    free(machine);

    return platform;
}

- (BOOL)canBlur {
    if(NSStringFromClass([UIVisualEffectView class]) && UIDevice.currentDevice.systemVersion.floatValue >= 8.0 && !UIAccessibilityIsReduceTransparencyEnabled()) {
        NSString *platform = self.platform;
        CGFloat deviceVersion = [[[platform stringByReplacingOccurrencesOfString:@"[^0-9,.]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, platform.length)] stringByReplacingOccurrencesOfString:@"," withString:@"."] floatValue];

        if([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"]) {
            return YES;
        } else if([platform rangeOfString:@"iPhone"].location != NSNotFound) {
            return (deviceVersion >= 4.1);
        } else if([platform rangeOfString:@"iPod"].location != NSNotFound) {
            return (deviceVersion >= 5.1);
        } else if([platform rangeOfString:@"iPad"].location != NSNotFound) {
            return (deviceVersion >= 3.4);
        }
    }

    return NO;
}

Важно помнить:
- включается/отключается только через системные настройки;
- blur (размытие) и прозрачность включается/отключается одновременно;
- в iOS 7 можно отключить эффект, но только в iOS 8 можно определить, отключен ли он. В самом приложении Apple только предлагает (но не настаивает) следить за прозрачностью, т.е. например можно сделать полупрозрачный элемент, когда в системе прозрачность отключена;
- поддержка blur на уровне ОС зависит не только от версии iOS, но и от типа устройства. Подробный список ниже.

Вариант 2. Определить поддержку конкретного устройства.
Первый способ хорош для компьютера, но не очень нагляден для человека. Здесь можно увидеть, какой строкой обозначается конкретная модель устройства в приложении:

http://stackoverflow.com/questions/448162/determine-device-iphone-ipod-touch-with-iphone-sdk

Дочерний UIView блокирует срабатывание события TouchesBegan для родительского UIView

Суть проблемы — событие TouchesBegan срабатывает непосредственно на view, которого касается пользователь. У superview по умолчанию событие не срабатывает.
Ссылка на решение проблемы:

http://stackoverflow.com/questions/12811848/subview-blocking-parent-view-touchesbegan

Решение — в дочернем UIView нужно прописать следующий код:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
   [super touchesBegan:touches withEvent:event];
   [self.nextResponder touchesBegan:touches withEvent:event];
}

Это передаст обработку событием «дальше».

Почему нельзя использовать retainCount

Источники:

http://whentouseretaincount.com

http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/

Более того — для объектов-констант xCode возвращает разные значения, например, для [NSNumber numberWithInt:1] и @»Foo».

Краткое содержание:
1)retainCount может изменяться при пропускании объекта через какое-либо системное API
2)возвращаемое значение может зависеть от специфики объектов
3)retainCount не учитывает autoreleased объекты
4)autorelease связано с потоками, а retainCount — глобальная величина
5)retainCount может никогда не вернуть ноль
6)синглтоны (в том числе системные)
7)некоторые классы могут манипулировать retainCount самостоятельно, т.е.вам нельзя использовать method-swizzling
8)команды retain/release потокобезопасны, а возвращаемое retainCount значение может оказаться неактуальным

iOS. Разница между singleton для ARC и не-ARC

Источник:

https://github.com/IgorFedorchuk/objective-c-style-guide

Исходный код

#if __has_feature(objc_arc) // ARC Version

#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname)	\
\
+ (classname *)sharedInstance\
{\
    static classname *shared##classname = nil;\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        shared##classname = [[self alloc] init];\
    });\
    return shared##classname;\
}

#else // Non-ARC Version

#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \
static classname *shared##classname = nil; \
+ (classname *)sharedInstance \
{ \
    @synchronized(self) \
    { \
        if (shared##classname == nil) \
        { \
            shared##classname = [[self alloc] init]; \
        } \
    } \
    return shared##classname; \
} \
\
+ (id)allocWithZone:(NSZone *)zone \
{ \
@synchronized(self) \
{ \
if (shared##classname == nil) \
{ \
shared##classname = [super allocWithZone:zone]; \
return shared##classname; \
} \
} \
return nil; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return self; \
} \
- (id)retain \
{ \
return self; \
} \
- (NSUInteger)retainCount \
{ \
return NSUIntegerMax; \
} \
- (oneway void)release \
{ \
} \
- (id)autorelease \
{ \
return self; \
}

#endif

Разница:
1)dispatch_once
2)статическая переменная объявлена внутри функции/вне ее (возможно, не имеет значения)

Используем OCMock не по назначению.

OCMock — фреймворк, предназначенный для тестирования приложений:

http://ocmock.org/

Кроме unit-тестов его можно использовать не по назначению, как альтернативу method swizzling.
Можно:
- подменить метод существующего объекта;
- создать объект некоторого класса и подменить в нем метод.
Нельзя заменить метод в классе так, чтобы класс создавал объекты с измененным методом.

Core Data + MagicalRecord. Пример работы с несколькими контекстами

Сначала инициализируем MagicalRecord. Создаем дочерний контекст и записываем в него что-нибудь, сохраняем в БД (после этого изменяется и родительский контекст).
Читаем из главного контекста, проверяем, что внесенные в дочерний контекст изменения появились в главном контексте.
Удаляем записи из дочернего контекста и применяем изменения без сохранения в БД. Эти изменения должны проявиться и в родительском контексте, но если остановить приложение на этом месте и перезапустить, то изменения исчезнут.
Далее пробуем сохранить изменения и в родительском контексте и в БД. Если после этого приложение перезапустить, то внесенные изменения останутся.

    [MagicalRecord setupCoreDataStack];
    NSManagedObjectContext *parentContext = [NSManagedObjectContext MR_defaultContext];

        NSManagedObjectContext *moc = [NSManagedObjectContext MR_contextWithParent:parentContext];
        BCExchange *exc = [BCExchange MR_createInContext:moc];
        exc.identifier = @"111";
        exc.name = @"ddddd";
        [moc MR_saveToPersistentStoreAndWait];
    
    {
        NSArray *arr = [BCExchange MR_findAllInContext:parentContext];
        NSLog(@"%d", arr.count);
    }
    
    [BCExchange MR_truncateAllInContext:moc];
    [moc MR_saveOnlySelfAndWait];
    {
        NSArray *arr = [BCExchange MR_findAllInContext:parentContext];
        NSLog(@"%d", arr.count);
    }
    
    [moc MR_saveToPersistentStoreAndWait];
    {
        NSArray *arr = [BCExchange MR_findAllInContext:parentContext];
        NSLog(@"%d", arr.count);
    }

xCode. Сбросить параметры target

В проекте xCode при сборке проекта берутся параметры для target. Если такие не заданы, то берутся из настроек проекта, общих для всех targets. Соответственно любое изменеие опции в target перекроет общие настройки.

Для сброса настройки в исходное положение нужно выбрать необходимую строку и нажать delete.

Баг с UITableView в новом xCode

Добавляю простую таблицу с одной custom ячейкой на UIVIewController (в Storyboard), задаю делегаты, определяю required (обязательные) делегатные методы, добавляю autolayout constraints. Получаю:
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell’s content view. We’re considering the collapse unintentional and using standard height instead.

Решение:
Необходимо дописать метод (tableView:heightForRowAtIndexPath:) делегата UITableViewDataSource. Без этого метода приложение не вылетает, но не может корректно определить высоту ячейки.

Неявное преобразование типов в Swift (implicit conversion)

Основная проблема Swift — это почти полное отсутствие неявного (implicit) приведения типов. Вы не сможете даже сложить 2 и 2.5 — целочисленное нужно будет привести к типу Double явно.

Также существует обходной путь — заставить приложение произвести действия над двумя числами (или объектами) через перегрузку операторов. Пример:

xCode. Size Classes

Оригинал — документация и презентации на сайте Apple.
Перевод:

http://habrahabr.ru/post/235181/

Суть технологии — облегчить программисту работу с экранами с разными разрешениями.

Для того, чтобы научиться пользоваться, не обязательно копировать все действия, описанные в данной статье.
Вместо этого попробуйте выложить 3 UIView’s в ряд и добиться того, чтобы левый прилегал к левому и верхнему краю, центральный — к центру и верхнему краю, правый — к правому и верхнему краю. При этом пусть они остаются квадратные и с какими-нибудь отступами между собой — на всех разновидностях устройств.

P.S. Важно помнить, что даже эта технология покрывает только всевозможные «физические» разрешения экранов и только частично учитывает (если учитывает вообще) «виртуальные» разрешения. Например, всевозможные экраны для iphone:

http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions