“Let’s talk collections”
   или кое-что о коллекциях в iOS.
Наиболее часто
используемые коллекции
                                iOS 2.0
• массивы: NS(Mutable)Array
• словари: NS(Mutable)Dictionary
• множества (наборы): NS(Mutable)Set
                                iOS 5.0
• упорядоченные множества:
  NS(Mutable)OrderedSet
Кое-что редко
             используемое
•   СF(Mutable)ArrayRef        ➡NS(Mutable)Array
•   СF(Mutable)DictionaryRef   ➡NS(Mutable)Dictionary
•   СF(Mutable)SetRef          ➡NS(Mutable)Set
•   CF(Mutable)BagRef          NSCountedSet

•   CFTreeRef, CFBinaryHeapRef N/A


• NSPointerArray                              iOS 6.0

• NSMapTable
• NSHashTable
Специализированные
          коллекции

•   NS(Mutable)IndexSet

•   NS(Mutable)CharacterSet /
    CF(Mutable)CharacterSetRef

•   CF(Mutable)BitVector
Прочее
• Массивы C, ex:     int array[] = { 10, 20 };


• STL, Boost, etc., ex:
                     std::vector<int> arr;


• Сторонние библиотеки:
 ‣ ReactiveCocoa
 ‣ NSEnumeratorLinq (After MS LINQ)
 ‣ Underscore.m (After Underscore.js)
 ‣ SOCQ
 ‣ ... etc
Новое в работе с коллекциями
                   iOS 6
         Версия
Элемент                                              Пример
        LLVM/iOS
                       @[ @10, @YES, @"String" ]
                       @{ @"Key 1" : @"Value 1", @10 : @YES }


Литералы      4/all    + (id)arrayWithObjects:(const id[])objects
                                  count:(NSUInteger)count;

                       + (id)dictionaryWithObjects:(const id[])objects
                                     forKeys:(const id<NSCopying>[])keys
                                       count:(NSUInteger)count;
                       array[index / 2] = @(index << 1)
                       dict[key] = @NO

Индексаци              - (id)objectAtIndexedSubscript:(NSUInteger)idx;

    я
             4/iOS 5   - (id)objectForKeyedSubscript:(id)key;

                       - (void)setObject:(id)obj
                       atIndexedSubscript:(NSUInteger)idx;

                       - (void)setObject:(id)obj
                       forKeyedSubscript:(id<NSCopying>)key;
                       // Immutable dictionary
Shared Key             + (id)sharedKeySetForKeys:(NSArray *)keys;
   Sets
               x/6     // Mutable dictionary
                       + (id)dictionaryWithSharedKeySet:(id)set;
Что есть NSArray?
NSArray
     NSMutableArray
          __NSArrayM
          __NSCFArray
          __NSPlaceholderArray
     NSKeyValueMutableArray
          NSKeyValueSlowMutableArray
          NSKeyValueNotifyingMutableArray
          NSKeyValueIvarMutableArray
          NSKeyValueFastMutableArray
             NSKeyValueFastMutableArray1
             NSKeyValueFastMutableArray2
     NSKeyValueArray
     __NSArrayI
     __NSArrayReversed
Препарируя NSArray...
@interface __NSArrayM : NSMutableArray {
    unsigned int _size : 30;
    unsigned int _offset : 30;
    id *_list;
    unsigned long _mutations;
  ... ... ...
}

- (void)rollObjectsInRange:(NSRange *)range
                by:(int)number;

- (void)trimObjectsFromIndex:(unsigned)index;

@end
Интересные методы в
                       NS(Mutable)Array
+ (id)arrayWithFloats:(float *)items count:(NSUInteger)count;
+ (id)arrayWithInts:(int *)items count:(NSUInteger)count;

- (BOOL)_validateValue:(id __unsafe_unretained *)value
         forKeyPath:(NSString *)keyPath
      ofObjectAtIndex:(NSUInteger)index error:(id *)error;
- (id)_mutableArrayValueForKeyPath:(NSString *)keyPath
             ofObjectAtIndex:(NSUInteger)index;
- (id)_mutableSetValueForKeyPath:(NSString *)keyPath
            ofObjectAtIndex:(NSUInteger)index;

- (id)_valueForKeyPath:(NSString *)keyPath
      ofObjectAtIndex:(NSUInteger)index;
- (void)_setValue:(id)value
      forKeyPath:(NSString *)keyPath
  ofObjectAtIndex:(NSUInteger)index;

- (BOOL)_kb_firstTwoObjectsEqual;
- (NSArray *)allObjectsWithClass:(Class)class;
- (id)arrayByApplyingSelector:(SEL)selector;
- (id)arrayByExcludingObjectsInArray:(NSArray *)objects;
- (id)arrayByReversingOrder;
- (NSUInteger)indexOfSmallestObject;
- (id)repeatedNTimes:(int)N;

- (void)enqueueObject:(id)object;
- (id)dequeueObject;
- (id)pop;
- (void)push:(id)object;
- (void)removeFirstObject;
- (void)shuffle;
Showtime
Новые коллекции в iOS
   Тип
            6 Назначение
                      Коллекция, могущая содержать NULL;
                  позволяющая задавать собственный размер
NSPointerArray   непосредственно. Позволяет задавать правила
                   управления элементами: как памятью, так и
                               интерпретацией.
                 Позволяет иметь слабые ссылки как на ключи,
                  так и на значения. Позволяет копировать/не
 NSMapTable        копировать ключи/значения. Класть в нее
                        можно и простые указатели. Все
                                настраивается.
                  Позволяет иметь слабые ссылки на значения.
                 Позволяет копировать/не копировать значения.
 NSHashTable      Класть в нее можно и простые указатели. Все
                                настраивается.
Создание и использование
              NSPointerArray, ...
- (id)initWithOptions:(NSPointerFunctionsOptions)options;

+ (id)initWithPointerFunctions:(NSPointerFunctions *)functions;
+ (id)strongObjectsPointerArray;
+ (id)weakObjectsPointerArray;

- (void)addPointer:(void *)pointer;
- (void)removePointerAtIndex:(NSUInteger)index;
- (void)insertPointer:(void *)item
          atIndex:(NSUInteger)index;
- (void)replacePointerAtIndex:(NSUInteger)index
             withPointer:(void *)item;
- (void *)pointerAtIndex:(NSUInteger)index;
- (NSArray *)allObjects;
- (void)setCount:(NSUInteger)count;
- (void)compact;
... NSMapTable, ...
- (id)initWithKeyOptions:(NSPointerFunctionsOptions)keys
          valueOptions:(NSPointerFunctionsOptions)values
            capacity:(NSUInteger)capacity;

- (id)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions
          valuePointerFunctions:(NSPointerFunctions *)valueFunctions
                 capacity:(NSUInteger)capacity;

+ (id)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions
         valueOptions:(NSPointerFunctionsOptions)valueOptions;

+ (id)strongToStrongObjectsMapTable;
+ (id)strongToWeakObjectsMapTable;
+ (id)weakToStrongObjectsMapTable;
+ (id)weakToWeakObjectsMapTable;

- (void)setObject:(id)value forKey:(id)key;
- (void)removeObjectForKey:(id)key;

- (NSDictionary *)dictionaryRepresentation;
... NSHashTable.
- (id)initWithOptions:(NSPointerFunctionsOptions)options
          capacity:(NSUInteger)capacity;

- (id)initWithPointerFunctions:(NSPointerFunctions *)functions
               capacity:(NSUInteger)capacity;

+ (id)hashTableWithOptions:(NSPointerFunctionsOptions)options;
+ (id)weakObjectsHashTable;

- (void)addObject:(id)object;
- (void)removeObject:(id)object;

- (NSArray *)allObjects;
- (id)anyObject;
- (BOOL)containsObject:(id)object;
- (id)member:(id)object;

- (NSSet *)setRepresentation;

- (BOOL)intersectsHashTable:(NSHashTable *)other;
- (BOOL)isSubsetOfHashTable:(NSHashTable *)other;

- (void)intersectHashTable:(NSHashTable *)other;
- (void)minusHashTable:(NSHashTable *)other;
- (void)unionHashTable:(NSHashTable *)other;
NSPointerFunctionsOptions
typedef NS_OPTIONS(NSUInteger, NSPointerFunctionsOptions) {
   NSPointerFunctionsStrongMemory = (0 << 0),
   NSPointerFunctionsOpaqueMemory = (2 << 0),
   NSPointerFunctionsMallocMemory = (3 << 0),
   NSPointerFunctionsMachVirtualMemory = (4 << 0),
   NSPointerFunctionsWeakMemory = (5UL << 0),

     NSPointerFunctionsObjectPersonality = (0 << 8),
     NSPointerFunctionsOpaquePersonality = (1 << 8),
     NSPointerFunctionsObjectPointerPersonality = (2 << 8),
     NSPointerFunctionsCStringPersonality = (3 << 8),
     NSPointerFunctionsStructPersonality = (4 << 8),
     NSPointerFunctionsIntegerPersonality = (5 << 8),

     NSPointerFunctionsCopyIn = (1 << 16),
};
NSMapTableOptions,
                       NSHashTableOptions
typedef NS_OPTIONS(NSUInteger, NSMapTableOptions) {
   NSMapTableStrongMemory = 0,
   NSMapTableCopyIn = NSPointerFunctionsCopyIn,
   NSMapTableWeakMemory = NSPointerFunctionsWeakMemory

     NSMapTableObjectPointerPersonality =
       NSPointerFunctionsObjectPointerPersonality,
};


typedef NS_OPTIONS(NSUInteger, NSHashTableOptions) {
   NSHashTableStrongMemory = 0,
   NSHashTableCopyIn = NSPointerFunctionsCopyIn,
   NSHashTableWeakMemory = NSPointerFunctionsWeakMemory

     NSHashTableObjectPointerPersonality =
       NSPointerFunctionsObjectPointerPersonality,
};
Showtime
Коллекции и KVC I
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;

- (id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath;

- (BOOL)validateValue:(inout id *)value
      forKeyPath:(NSString *)keyPath
         error:(out NSError * __autoreleasing *)error;
Коллекции и KVC II
                     - (id)valueForKey:             - (void)setValue:(id)value
                     (NSString *)key;               forKey:(NSString *)key;
                                                    setObject:forKey:, если value !
NSDictionary (I/M)    То же, что и objectForKey:            = nil; иначе,
                                                        removeObjectForKey:

                         Массив результатов
  NSArray (I/M)        valueForKey: над каждым
                     элементом (NSNull если nil).

                       Множество результатов
                       valueForKey: над каждым
   NSSet (I/M)        элементом (nil опускается,    setValue:forKey: над каждым
                       дубликаты опускаются).                элементом.

                      Упорядоченное множество
                     результатов valueForKey: над
NSOrderedSet (I/M)      каждым элементом (nil
                        опускается, дубликаты
                             опускаются).
Коллекции и KVC III
Person *oldestPerson = [people valueForKeyPath:@"@max.age"];

NSArray *uniqueNamesOfSiblings =
  [person valueForKeyPath:@"mother.children.@distinctUnionOfArrays.name"];

NSPredicate *predicate =
  [NSPredicate predicateWithFormat:@"name BEGINSWITH 'J' AND age >= 18"];
NSArray *allAdultJs = [people filteredArrayUsingPredicate:predicate];

NSPredicate *predicate =
  [NSPredicate predicateWithFormat:
     @"FUNCTION(SELF, "capitalizedString") BEGINSWITH[cd] 'H'"
  ];
NSArray *startingFromCapitalH = [
  @[ @"hello", @"world" ] filteredArrayUsingPredicate:predicate
];
Доступные функции
         Функция
                 KVCМетоды NSArray
@avg                      - (id)_avgForKeyPath:(NSString *)keyPath;


@count                    - (id)_countForKeyPath:(NSString *)keyPath;


@distinctUnionOfArrays    - (id)_distinctUnionOfArraysForKeyPath:(NSString *)keyPath;


@distinctUnionOfObjects   - (id)_distinctUnionOfObjectsForKeyPath:(NSString *)keyPath;


@distinctUnionOfSets      - (id)_distinctUnionOfSetsForKeyPath:(NSString *)keyPath;


@max                      - (id)_maxForKeyPath:(NSString *)keyPath;


@min                      - (id)_minForKeyPath:(NSString *)keyPath;


@sum                      - (id)_sumForKeyPath:(NSString *)keyPath;


@unionOfArrays            - (id)_unionOfArraysForKeyPath:(NSString *)keyPath;


@unionOfObjects           - (id)_unionOfObjectsForKeyPath:(NSString *)keyPath;


@unionOfSets              - (id)_unionOfSetsKeyPath:(NSString *)keyPath;
Что есть предикаты?
NSPredicate
    NSCompoundPredicate
    NSComparisonPredicate
    NSBlockPredicate
    NSTruePredicate
    NSFalsePredicate
Создание предикатов
+ (P)predicateWithFormat:(S)predicateFormat, ...

+ (P)andPredicateWithSubpredicates:(A)subpredicates;

+ (P)orPredicateWithSubpredicates:(A)subpredicates;

+ (P)notPredicateWithSubpredicate:(P)predicate;


+ (P)predicateWithLeftExpression:(E)lhs rightExpression:(E)rhs
              modifier:(NSComparisonPredicateModifier)modifier
                 type:(NSPredicateOperatorType)type
               options:(NSComparisonPredicateOptions)options;

+ (P)predicateWithLeftExpression:(E)lhs rightExpression:(E)rhs customSelector:(SEL)selector;
       typedef NS_ENUM(NSUInteger,                                      typedef NS_OPTIONS(NSUInteger,
              NSPredicateOperatorType) {                                        NSComparisonPredicateOptions) {
          NSLessThanPredicateOperatorType,                                 NSCaseInsensitivePredicateOption,
          NSLessThanOrEqualToPredicateOperatorType,                        NSDiacriticInsensitivePredicateOption,
          NSGreaterThanPredicateOperatorType,                              NSNormalizedPredicateOption
          NSGreaterThanOrEqualToPredicateOperatorType,                  };
          NSEqualToPredicateOperatorType,
          NSNotEqualToPredicateOperatorType,                            typedef NS_ENUM(NSUInteger,
          NSMatchesPredicateOperatorType,                                       NSComparisonPredicateModifier) {
          NSLikePredicateOperatorType,                                     NSDirectPredicateModifier,
          NSBeginsWithPredicateOperatorType,                               NSAllPredicateModifier,
          NSEndsWithPredicateOperatorType,                                 NSAnyPredicateModifier
          NSInPredicateOperatorType,                                    };
          NSCustomSelectorPredicateOperatorType,
          NSContainsPredicateOperatorType,
          NSBetweenPredicateOperatorType
       };
Выражения+(E)expressionForBlock:(id(^)(id evaluatedObject,
NSExpression
                                        NSArray *expressions, NSMutableDictionary *context))block
                                              arguments:(NSArray *)arguments;
      NSAggregateExpression
                                       +(E)expressionForAggregate:(A)values;
      NSAnyKeyExpression               +(E)expressionForConstantValue:(id)value;
                                       +(E)expressionForEvaluatedObject;
      NSBlockExpression                +(E)expressionForVariable:(S)variable;
                                       +(E)expressionForKeyPath:(S)keyPath;
      NSConstantValueExpression
                                       +(E)expressionForFunction:(S)name
      NSFunctionExpression                      arguments:(A)arguments;

               NSKeyPathExpression     +(E)expressionForFunction:(S)name
                                              selectorName:(S)selectorName
      NSKeyPathSpecifierExpression              arguments:(A)arguments;

      NSSelfExpression                 +(E)expressionForIntersectSet:(E)left
                                                      with:(E)right;
                                       +(E)expressionForMinusSet:(E)left
      NSSetExpression                              with:(E)right;
                                       +(E)expressionForUnionSet:(E)left
      NSSubqueryExpression                         with:(E)right;

      NSSymbolicExpression             +(E)expressionForSubquery:(E)expression
                                         usingIteratorVariable:(S)variable
      NSTernaryExpression                        predicate:(P)predicate;

      NSVariableAssignmentExpression   +(E)expressionForSymbolicString:(S)string;
                                       +(E)expressionForTernaryWithPredicate:(P)predicate
      NSVariableExpression                trueExpression:(E)te falseExpression:(E)fe;
                                       +(E)expressionForVariableNameAssignment:(S)variableName
                                                           expression:(E)expression;
Функции предикатов
      Литерал                      Метод         Литерал                          Метод
                        add:to:                                       min:
                                             min(a), max(a),
                        from:subtract:                                max:
+, -, *, /, %           multiply:by:         sum(a)                   sum:
                        divide:by:
                        modulus:by:          average(a),              average:
                        raise:toPower:       stddev(a),               stddev:
                        leftshift:by:        median(a),               median:
**, <<, >>, sqrt(v)     rightshift:by:       mode(a)                  mode:
                        sqrt:
                        bitwiseAnd:with:     a[SIZE]                  count:
                        bitwiseOr:with:      a[index]                 objectFrom:withIndex:
&, |, ^, ~              bitwiseXor:with:
                        onesComplement:
                                             DISTINCT                 distinct:
CAST(value, “TYPE”)     castObject:toType:   noindex(v)               noindex:

                        ceiling:                                      exp:
ceiling(v), floor(v),                        exp(v), ln(v), log(v),
                        floor:                                        ln:
trunc(v)                trunc:               abs(v)                   log:
                                                                      abs:
                        random
random, randomn(v)      randomn:             lowercase(v),            lowercase:
now                     now                  uppercase(v)             uppercase:
Showtime
Коллекции и KVO I
    NSArray/NSMutableArray                              NSSet/NSMutableSet
       KVC-Compliance                                    KVC-Compliance
•   Импелементировать -<key>.
•   ИЛИ завести ivar <key> или _<key>.
                                                 •   Импелементировать -<key>.
•   ИЛИ имплементировать -countOf<Key> И
                                                 •   ИЛИ завести ivar <key> или _<key>.
    один или оба -objectIn<Key>AtIndex: и/или
    -<key>AtIndexes:.
                                                 •   ИЛИ имплементировать -countOf<Key>,
                                                     -enumeratorOf<Key>, и -memberOf<Key>
•   Для улучшения производительности
    имплементировать -get<Key>:range:.

•  Импелементировать один или оба
   -insertObject:in<Key>AtIndex: и/или
   -insert<Key>:atIndexes:.
                                                 •  Импелементировать один или оба
                                                    -add<Key>Object: и/или -add<Key>:.
•  Импелементировать один или оба
   -removeObjectFrom<Key>AtIndex: и/или          •  Импелементировать один или оба
                                                    -remove<Key>Object: и/или -remove<Key>:.
   -remove<Key>AtIndexes:.
•  Для улучшения производительности              •  Для улучшения производительности
                                                    имплементировать
   имплементировать
                                                 -intersect<Key>: и/или -set<Key>:.
-replaceObjectIn<Key>AtIndex:withObject: и/или
   -replace<Key>AtIndexes:with<Key>:.
Коллекции и KVO II

• NSArray, NSOrderedSet, NSSet:
 ‣ Нельзя вызывать addObserver:forKeyPath:options:context:
• NSArray
 ‣ Можно вызывать
  addObserver:toObjectsAtIndexes:forKeyPath:options:context:

• NSDictionary
 ‣ Можно вызывать addObserver:forKeyPath:options:context:
Коллекции и KVO III
- (void)willChangeValueForKey:(NSString *)key;

- (void)willChange:(NSKeyValueChange)change
   valuesAtIndexes:(NSIndexSet *)indexes
        forKey:(NSString *)key;

- (void)willChangeValueForKey:(NSString *)key
         withSetMutation:(NSKeyValueSetMutationKind)mutationKind
            usingObjects:(NSSet *)objects;

- (void)didChangeValueForKey:(NSString *)key;

- (void)didChange:(NSKeyValueChange)change
  valuesAtIndexes:(NSIndexSet *)indexes
        forKey:(NSString *)key;

- (void)didChangeValueForKey:(NSString *)key
         withSetMutation:(NSKeyValueSetMutationKind)mutationKind
           usingObjects:(NSSet *)objects;
        typedef NS_OPTIONS(NSUInteger,               NSString *const NSKeyValueChangeKindKey;
               NSKeyValueChange) {                   NSString *const NSKeyValueChangeNewKey;
           NSKeyValueChangeSetting,                  NSString *const NSKeyValueChangeOldKey;
           NSKeyValueChangeInsertion,                NSString *const NSKeyValueChangeIndexesKey;
           NSKeyValueChangeRemoval,                  NSString *const NSKeyValueChangeNotificationIsPriorKey;
           NSKeyValueChangeReplacement
        };                                           typedef NS_OPTIONS(NSUInteger,
        typedef NS_OPTIONS(NSUInteger,                      NSKeyValueObservingOptions) {
               NSKeyValueSetMutationKind) {             NSKeyValueObservingOptionNew,
           NSKeyValueUnionSetMutation,                  NSKeyValueObservingOptionOld,
           NSKeyValueMinusSetMutation,                  NSKeyValueObservingOptionInitial,
           NSKeyValueIntersectSetMutation,              NSKeyValueObservingOptionPrior
           NSKeyValueSetSetMutation                  };
        };
Showtime
Core Foundation
• CFArrayRef / CFMutableArrayRef
• CFDictionaryRef / CFMutableDictionaryRef
• CFSetRef / CFMutableSetRef
• CFBagRef / CFMutableBagRef
• CFTreeRef
• CFBinaryHeapRef
Особенности CF-
                    коллекций
    Особенность                              Способ определения
                                 CFArrayCreateMutable(
                                    kCFAllocatorDefault,
Могут быть как fixed-size, так      <NUMBER_OF_ITEMS>,
       и variable-size.             &kCFTypeArrayCallBacks
                                 );
                                 Если <NUMBER_OF_ITEMS> == 0, то variable-size
                                 CFArrayCallBacks,
     Поведение при               CFDictionaryKeyCallBacks,
добавлении/удалении/поиск        CFDictionaryValueCallBacks,
                                 CFSetCallBacks,
е элементов определяется         CFBagCallBacks,
      при создании.              CFTreeContext,
                                 CFBinaryHeapCallBacks/CFBinaryHeapCompareContext
                                 CFArrayRef a = (__bridge_retained CFArrayRef)[NSArray new];
    CF(Mutable)ArrayRef,         CFArrayRef a = (__bridge CFArrayRef)[NSArray array];
  CF(Mutable)DictionaryRef,      NSArray *a = (__bridge_transfer NSArray *) CFArrayCreate(
                                    0,
 CF(Mutable)SetRef - toll-free      (const void **) &(CFStringRef *){
          bridged.                     CFSTR("1"),
                                       NULL
Можно класть NULL или ints          },
                                    2,
с размерностью указателя.           NULL
                                 );
Коллекция                                 Callback                            Predefined
              typedef struct {
                 CFIndex version;
                 CFArrayRetainCallBack retain;
  Array          CFArrayReleaseCallBack release;
                 CFArrayCopyDescriptionCallBack copyDescription;
                                                                     kCFTypeArrayCallBacks

                 CFArrayEqualCallBack equal;
              } CFArrayCallBacks;
              typedef struct {
                 // ...Like in prefixed prefixed CFDictionary
                 CFDictionaryHashCallBack hash;                      kCFTypeDictionaryKeyCallBacks
Dictionary    } CFDictionaryKeyCallBacks;

              typedef struct {
                                                                     kCFCopyStringDictionaryKeyCallBacks
                                                                     kCFTypeDictionaryValueCallBacks
                 // ...Like in array prefixed CFDictionary
              } CFDictionaryValueCallBacks;
              typedef struct {                                       kCFTypeSetCallBacks

  Set/Bag        // ...Like in dictionary but prefixed CFSet/CFBag
              } CFSet(Bag)CallBacks;
                                                                     kCFCopyStringSetCallBacks
                                                                     kCFTypeBagCallBacks
                                                                     kCFCopyStringBagCallBacks
              typedef struct {
                 CFIndex version;

   Tree
                 void *info;
                 CFTreeRetainCallBack retain;
                 CFTreeReleaseCallBack release;
                 CFTreeCopyDescriptionCallBack copyDescription;
              } CFTreeContext;
              typedef struct {
                 CFIndex version;
                 const void *(*retain)
                   (CFAllocatorRef allocator, const void *ptr);
                 void        (*release)
Binary Heap        (CFAllocatorRef allocator, const void *ptr);
                 CFStringRef (*copyDescription)(const void *ptr);
                                                                     kCFStringBinaryHeapCallBacks

                 CFComparisonResult (*compare)
                   (const void *ptr1,
                    const void *ptr2,
                    void *context);
              } CFBinaryHeapCallBacks;
Эффективность
                реализации
                  Вставка             Доступ           Поиск
                  worst/avg          worst/avg        worst/avg
                                                   O(N*lg N) /
  CFArray      O(N*lg N) / O(N)   O(lg N) / O(1)
                                                   < O(N*lg N)



CFDictionary   O(N*N) / O(1)      < O(N)           O(N) / O(1)




   CFSet       O(N*N) / O(1)      < O(N)           O(N) / O(1)




   CFBag       O(N*N) / O(1)      < O(N)           O(N) / O(1)
CFTreeRef
• Связь от одного parent к N children.
• Parent - владелец children. У children - слабые
  ссылки на Parent.
• Root тот, у кого нет ссылки на Parent.
• Контекст, заданный при создании Node,
  определяет правила управления памятью и
  получения описания над этим Node.
• Как правило, в функции работы с деревьями
  передается указатель на Parent Node, а
  операция осуществляется в отношении Child
  Node.
CFBinaryHeap
• Хранит значения в отсортированном виде.
• Любое новое значение встраивается в
  порядок, сохраняя сортировку.
• Позволяет скорейшим образом получить
  минимум набора значений, но не максимум
  (особенности реализации).
• Функция сравнения задается в поле compare в
  описателе при создании CFBinaryHeap.
• Правила управления памятью объектов в
  коллекции также задаются в описателе.
Showtime
That’s all, folks!
•   http://opensource.apple.com/source/CF/CF-744.12/
•   http://funwithobjc.tumblr.com/post/2922267976/using-custom
•   http://kickingbear.com/blog/archives/9
•   https://github.com/nst/iOS-Runtime-Headers
•   Apple Documentation

•   Презентация на Slideshare:
    http://www.slideshare.net/comfly/talks-on-collections
•   Код на Github:
    https://github.com/comfly/CollectionSamples

Talks on collections

  • 1.
    “Let’s talk collections” или кое-что о коллекциях в iOS.
  • 2.
    Наиболее часто используемые коллекции iOS 2.0 • массивы: NS(Mutable)Array • словари: NS(Mutable)Dictionary • множества (наборы): NS(Mutable)Set iOS 5.0 • упорядоченные множества: NS(Mutable)OrderedSet
  • 3.
    Кое-что редко используемое • СF(Mutable)ArrayRef ➡NS(Mutable)Array • СF(Mutable)DictionaryRef ➡NS(Mutable)Dictionary • СF(Mutable)SetRef ➡NS(Mutable)Set • CF(Mutable)BagRef NSCountedSet • CFTreeRef, CFBinaryHeapRef N/A • NSPointerArray iOS 6.0 • NSMapTable • NSHashTable
  • 4.
    Специализированные коллекции • NS(Mutable)IndexSet • NS(Mutable)CharacterSet / CF(Mutable)CharacterSetRef • CF(Mutable)BitVector
  • 5.
    Прочее • Массивы C,ex: int array[] = { 10, 20 }; • STL, Boost, etc., ex: std::vector<int> arr; • Сторонние библиотеки: ‣ ReactiveCocoa ‣ NSEnumeratorLinq (After MS LINQ) ‣ Underscore.m (After Underscore.js) ‣ SOCQ ‣ ... etc
  • 6.
    Новое в работес коллекциями iOS 6 Версия Элемент Пример LLVM/iOS @[ @10, @YES, @"String" ] @{ @"Key 1" : @"Value 1", @10 : @YES } Литералы 4/all + (id)arrayWithObjects:(const id[])objects count:(NSUInteger)count; + (id)dictionaryWithObjects:(const id[])objects forKeys:(const id<NSCopying>[])keys count:(NSUInteger)count; array[index / 2] = @(index << 1) dict[key] = @NO Индексаци - (id)objectAtIndexedSubscript:(NSUInteger)idx; я 4/iOS 5 - (id)objectForKeyedSubscript:(id)key; - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx; - (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key; // Immutable dictionary Shared Key + (id)sharedKeySetForKeys:(NSArray *)keys; Sets x/6 // Mutable dictionary + (id)dictionaryWithSharedKeySet:(id)set;
  • 7.
    Что есть NSArray? NSArray NSMutableArray __NSArrayM __NSCFArray __NSPlaceholderArray NSKeyValueMutableArray NSKeyValueSlowMutableArray NSKeyValueNotifyingMutableArray NSKeyValueIvarMutableArray NSKeyValueFastMutableArray NSKeyValueFastMutableArray1 NSKeyValueFastMutableArray2 NSKeyValueArray __NSArrayI __NSArrayReversed
  • 8.
    Препарируя NSArray... @interface __NSArrayM: NSMutableArray { unsigned int _size : 30; unsigned int _offset : 30; id *_list; unsigned long _mutations; ... ... ... } - (void)rollObjectsInRange:(NSRange *)range by:(int)number; - (void)trimObjectsFromIndex:(unsigned)index; @end
  • 9.
    Интересные методы в NS(Mutable)Array + (id)arrayWithFloats:(float *)items count:(NSUInteger)count; + (id)arrayWithInts:(int *)items count:(NSUInteger)count; - (BOOL)_validateValue:(id __unsafe_unretained *)value forKeyPath:(NSString *)keyPath ofObjectAtIndex:(NSUInteger)index error:(id *)error; - (id)_mutableArrayValueForKeyPath:(NSString *)keyPath ofObjectAtIndex:(NSUInteger)index; - (id)_mutableSetValueForKeyPath:(NSString *)keyPath ofObjectAtIndex:(NSUInteger)index; - (id)_valueForKeyPath:(NSString *)keyPath ofObjectAtIndex:(NSUInteger)index; - (void)_setValue:(id)value forKeyPath:(NSString *)keyPath ofObjectAtIndex:(NSUInteger)index; - (BOOL)_kb_firstTwoObjectsEqual; - (NSArray *)allObjectsWithClass:(Class)class; - (id)arrayByApplyingSelector:(SEL)selector; - (id)arrayByExcludingObjectsInArray:(NSArray *)objects; - (id)arrayByReversingOrder; - (NSUInteger)indexOfSmallestObject; - (id)repeatedNTimes:(int)N; - (void)enqueueObject:(id)object; - (id)dequeueObject; - (id)pop; - (void)push:(id)object; - (void)removeFirstObject; - (void)shuffle;
  • 10.
  • 11.
    Новые коллекции вiOS Тип 6 Назначение Коллекция, могущая содержать NULL; позволяющая задавать собственный размер NSPointerArray непосредственно. Позволяет задавать правила управления элементами: как памятью, так и интерпретацией. Позволяет иметь слабые ссылки как на ключи, так и на значения. Позволяет копировать/не NSMapTable копировать ключи/значения. Класть в нее можно и простые указатели. Все настраивается. Позволяет иметь слабые ссылки на значения. Позволяет копировать/не копировать значения. NSHashTable Класть в нее можно и простые указатели. Все настраивается.
  • 12.
    Создание и использование NSPointerArray, ... - (id)initWithOptions:(NSPointerFunctionsOptions)options; + (id)initWithPointerFunctions:(NSPointerFunctions *)functions; + (id)strongObjectsPointerArray; + (id)weakObjectsPointerArray; - (void)addPointer:(void *)pointer; - (void)removePointerAtIndex:(NSUInteger)index; - (void)insertPointer:(void *)item atIndex:(NSUInteger)index; - (void)replacePointerAtIndex:(NSUInteger)index withPointer:(void *)item; - (void *)pointerAtIndex:(NSUInteger)index; - (NSArray *)allObjects; - (void)setCount:(NSUInteger)count; - (void)compact;
  • 13.
    ... NSMapTable, ... -(id)initWithKeyOptions:(NSPointerFunctionsOptions)keys valueOptions:(NSPointerFunctionsOptions)values capacity:(NSUInteger)capacity; - (id)initWithKeyPointerFunctions:(NSPointerFunctions *)keyFunctions valuePointerFunctions:(NSPointerFunctions *)valueFunctions capacity:(NSUInteger)capacity; + (id)mapTableWithKeyOptions:(NSPointerFunctionsOptions)keyOptions valueOptions:(NSPointerFunctionsOptions)valueOptions; + (id)strongToStrongObjectsMapTable; + (id)strongToWeakObjectsMapTable; + (id)weakToStrongObjectsMapTable; + (id)weakToWeakObjectsMapTable; - (void)setObject:(id)value forKey:(id)key; - (void)removeObjectForKey:(id)key; - (NSDictionary *)dictionaryRepresentation;
  • 14.
    ... NSHashTable. - (id)initWithOptions:(NSPointerFunctionsOptions)options capacity:(NSUInteger)capacity; - (id)initWithPointerFunctions:(NSPointerFunctions *)functions capacity:(NSUInteger)capacity; + (id)hashTableWithOptions:(NSPointerFunctionsOptions)options; + (id)weakObjectsHashTable; - (void)addObject:(id)object; - (void)removeObject:(id)object; - (NSArray *)allObjects; - (id)anyObject; - (BOOL)containsObject:(id)object; - (id)member:(id)object; - (NSSet *)setRepresentation; - (BOOL)intersectsHashTable:(NSHashTable *)other; - (BOOL)isSubsetOfHashTable:(NSHashTable *)other; - (void)intersectHashTable:(NSHashTable *)other; - (void)minusHashTable:(NSHashTable *)other; - (void)unionHashTable:(NSHashTable *)other;
  • 15.
    NSPointerFunctionsOptions typedef NS_OPTIONS(NSUInteger, NSPointerFunctionsOptions){ NSPointerFunctionsStrongMemory = (0 << 0), NSPointerFunctionsOpaqueMemory = (2 << 0), NSPointerFunctionsMallocMemory = (3 << 0), NSPointerFunctionsMachVirtualMemory = (4 << 0), NSPointerFunctionsWeakMemory = (5UL << 0), NSPointerFunctionsObjectPersonality = (0 << 8), NSPointerFunctionsOpaquePersonality = (1 << 8), NSPointerFunctionsObjectPointerPersonality = (2 << 8), NSPointerFunctionsCStringPersonality = (3 << 8), NSPointerFunctionsStructPersonality = (4 << 8), NSPointerFunctionsIntegerPersonality = (5 << 8), NSPointerFunctionsCopyIn = (1 << 16), };
  • 16.
    NSMapTableOptions, NSHashTableOptions typedef NS_OPTIONS(NSUInteger, NSMapTableOptions) { NSMapTableStrongMemory = 0, NSMapTableCopyIn = NSPointerFunctionsCopyIn, NSMapTableWeakMemory = NSPointerFunctionsWeakMemory NSMapTableObjectPointerPersonality = NSPointerFunctionsObjectPointerPersonality, }; typedef NS_OPTIONS(NSUInteger, NSHashTableOptions) { NSHashTableStrongMemory = 0, NSHashTableCopyIn = NSPointerFunctionsCopyIn, NSHashTableWeakMemory = NSPointerFunctionsWeakMemory NSHashTableObjectPointerPersonality = NSPointerFunctionsObjectPointerPersonality, };
  • 17.
  • 18.
    Коллекции и KVCI - (id)valueForKey:(NSString *)key; - (void)setValue:(id)value forKey:(NSString *)key; - (id)valueForKeyPath:(NSString *)keyPath; - (void)setValue:(id)value forKeyPath:(NSString *)keyPath; - (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath; - (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath; - (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath; - (BOOL)validateValue:(inout id *)value forKeyPath:(NSString *)keyPath error:(out NSError * __autoreleasing *)error;
  • 19.
    Коллекции и KVCII - (id)valueForKey: - (void)setValue:(id)value (NSString *)key; forKey:(NSString *)key; setObject:forKey:, если value ! NSDictionary (I/M) То же, что и objectForKey: = nil; иначе, removeObjectForKey: Массив результатов NSArray (I/M) valueForKey: над каждым элементом (NSNull если nil). Множество результатов valueForKey: над каждым NSSet (I/M) элементом (nil опускается, setValue:forKey: над каждым дубликаты опускаются). элементом. Упорядоченное множество результатов valueForKey: над NSOrderedSet (I/M) каждым элементом (nil опускается, дубликаты опускаются).
  • 20.
    Коллекции и KVCIII Person *oldestPerson = [people valueForKeyPath:@"@max.age"]; NSArray *uniqueNamesOfSiblings = [person valueForKeyPath:@"mother.children.@distinctUnionOfArrays.name"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'J' AND age >= 18"]; NSArray *allAdultJs = [people filteredArrayUsingPredicate:predicate]; NSPredicate *predicate = [NSPredicate predicateWithFormat: @"FUNCTION(SELF, "capitalizedString") BEGINSWITH[cd] 'H'" ]; NSArray *startingFromCapitalH = [ @[ @"hello", @"world" ] filteredArrayUsingPredicate:predicate ];
  • 21.
    Доступные функции Функция KVCМетоды NSArray @avg - (id)_avgForKeyPath:(NSString *)keyPath; @count - (id)_countForKeyPath:(NSString *)keyPath; @distinctUnionOfArrays - (id)_distinctUnionOfArraysForKeyPath:(NSString *)keyPath; @distinctUnionOfObjects - (id)_distinctUnionOfObjectsForKeyPath:(NSString *)keyPath; @distinctUnionOfSets - (id)_distinctUnionOfSetsForKeyPath:(NSString *)keyPath; @max - (id)_maxForKeyPath:(NSString *)keyPath; @min - (id)_minForKeyPath:(NSString *)keyPath; @sum - (id)_sumForKeyPath:(NSString *)keyPath; @unionOfArrays - (id)_unionOfArraysForKeyPath:(NSString *)keyPath; @unionOfObjects - (id)_unionOfObjectsForKeyPath:(NSString *)keyPath; @unionOfSets - (id)_unionOfSetsKeyPath:(NSString *)keyPath;
  • 22.
    Что есть предикаты? NSPredicate NSCompoundPredicate NSComparisonPredicate NSBlockPredicate NSTruePredicate NSFalsePredicate
  • 23.
    Создание предикатов + (P)predicateWithFormat:(S)predicateFormat,... + (P)andPredicateWithSubpredicates:(A)subpredicates; + (P)orPredicateWithSubpredicates:(A)subpredicates; + (P)notPredicateWithSubpredicate:(P)predicate; + (P)predicateWithLeftExpression:(E)lhs rightExpression:(E)rhs modifier:(NSComparisonPredicateModifier)modifier type:(NSPredicateOperatorType)type options:(NSComparisonPredicateOptions)options; + (P)predicateWithLeftExpression:(E)lhs rightExpression:(E)rhs customSelector:(SEL)selector; typedef NS_ENUM(NSUInteger, typedef NS_OPTIONS(NSUInteger, NSPredicateOperatorType) { NSComparisonPredicateOptions) { NSLessThanPredicateOperatorType, NSCaseInsensitivePredicateOption, NSLessThanOrEqualToPredicateOperatorType, NSDiacriticInsensitivePredicateOption, NSGreaterThanPredicateOperatorType, NSNormalizedPredicateOption NSGreaterThanOrEqualToPredicateOperatorType, }; NSEqualToPredicateOperatorType, NSNotEqualToPredicateOperatorType, typedef NS_ENUM(NSUInteger, NSMatchesPredicateOperatorType, NSComparisonPredicateModifier) { NSLikePredicateOperatorType, NSDirectPredicateModifier, NSBeginsWithPredicateOperatorType, NSAllPredicateModifier, NSEndsWithPredicateOperatorType, NSAnyPredicateModifier NSInPredicateOperatorType, }; NSCustomSelectorPredicateOperatorType, NSContainsPredicateOperatorType, NSBetweenPredicateOperatorType };
  • 24.
    Выражения+(E)expressionForBlock:(id(^)(id evaluatedObject, NSExpression NSArray *expressions, NSMutableDictionary *context))block arguments:(NSArray *)arguments; NSAggregateExpression +(E)expressionForAggregate:(A)values; NSAnyKeyExpression +(E)expressionForConstantValue:(id)value; +(E)expressionForEvaluatedObject; NSBlockExpression +(E)expressionForVariable:(S)variable; +(E)expressionForKeyPath:(S)keyPath; NSConstantValueExpression +(E)expressionForFunction:(S)name NSFunctionExpression arguments:(A)arguments; NSKeyPathExpression +(E)expressionForFunction:(S)name selectorName:(S)selectorName NSKeyPathSpecifierExpression arguments:(A)arguments; NSSelfExpression +(E)expressionForIntersectSet:(E)left with:(E)right; +(E)expressionForMinusSet:(E)left NSSetExpression with:(E)right; +(E)expressionForUnionSet:(E)left NSSubqueryExpression with:(E)right; NSSymbolicExpression +(E)expressionForSubquery:(E)expression usingIteratorVariable:(S)variable NSTernaryExpression predicate:(P)predicate; NSVariableAssignmentExpression +(E)expressionForSymbolicString:(S)string; +(E)expressionForTernaryWithPredicate:(P)predicate NSVariableExpression trueExpression:(E)te falseExpression:(E)fe; +(E)expressionForVariableNameAssignment:(S)variableName expression:(E)expression;
  • 25.
    Функции предикатов Литерал Метод Литерал Метод add:to: min: min(a), max(a), from:subtract: max: +, -, *, /, % multiply:by: sum(a) sum: divide:by: modulus:by: average(a), average: raise:toPower: stddev(a), stddev: leftshift:by: median(a), median: **, <<, >>, sqrt(v) rightshift:by: mode(a) mode: sqrt: bitwiseAnd:with: a[SIZE] count: bitwiseOr:with: a[index] objectFrom:withIndex: &, |, ^, ~ bitwiseXor:with: onesComplement: DISTINCT distinct: CAST(value, “TYPE”) castObject:toType: noindex(v) noindex: ceiling: exp: ceiling(v), floor(v), exp(v), ln(v), log(v), floor: ln: trunc(v) trunc: abs(v) log: abs: random random, randomn(v) randomn: lowercase(v), lowercase: now now uppercase(v) uppercase:
  • 26.
  • 27.
    Коллекции и KVOI NSArray/NSMutableArray NSSet/NSMutableSet KVC-Compliance KVC-Compliance • Импелементировать -<key>. • ИЛИ завести ivar <key> или _<key>. • Импелементировать -<key>. • ИЛИ имплементировать -countOf<Key> И • ИЛИ завести ivar <key> или _<key>. один или оба -objectIn<Key>AtIndex: и/или -<key>AtIndexes:. • ИЛИ имплементировать -countOf<Key>, -enumeratorOf<Key>, и -memberOf<Key> • Для улучшения производительности имплементировать -get<Key>:range:. • Импелементировать один или оба -insertObject:in<Key>AtIndex: и/или -insert<Key>:atIndexes:. • Импелементировать один или оба -add<Key>Object: и/или -add<Key>:. • Импелементировать один или оба -removeObjectFrom<Key>AtIndex: и/или • Импелементировать один или оба -remove<Key>Object: и/или -remove<Key>:. -remove<Key>AtIndexes:. • Для улучшения производительности • Для улучшения производительности имплементировать имплементировать -intersect<Key>: и/или -set<Key>:. -replaceObjectIn<Key>AtIndex:withObject: и/или -replace<Key>AtIndexes:with<Key>:.
  • 28.
    Коллекции и KVOII • NSArray, NSOrderedSet, NSSet: ‣ Нельзя вызывать addObserver:forKeyPath:options:context: • NSArray ‣ Можно вызывать addObserver:toObjectsAtIndexes:forKeyPath:options:context: • NSDictionary ‣ Можно вызывать addObserver:forKeyPath:options:context:
  • 29.
    Коллекции и KVOIII - (void)willChangeValueForKey:(NSString *)key; - (void)willChange:(NSKeyValueChange)change valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key; - (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects; - (void)didChangeValueForKey:(NSString *)key; - (void)didChange:(NSKeyValueChange)change valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key; - (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects; typedef NS_OPTIONS(NSUInteger, NSString *const NSKeyValueChangeKindKey; NSKeyValueChange) { NSString *const NSKeyValueChangeNewKey; NSKeyValueChangeSetting, NSString *const NSKeyValueChangeOldKey; NSKeyValueChangeInsertion, NSString *const NSKeyValueChangeIndexesKey; NSKeyValueChangeRemoval, NSString *const NSKeyValueChangeNotificationIsPriorKey; NSKeyValueChangeReplacement }; typedef NS_OPTIONS(NSUInteger, typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) { NSKeyValueSetMutationKind) { NSKeyValueObservingOptionNew, NSKeyValueUnionSetMutation, NSKeyValueObservingOptionOld, NSKeyValueMinusSetMutation, NSKeyValueObservingOptionInitial, NSKeyValueIntersectSetMutation, NSKeyValueObservingOptionPrior NSKeyValueSetSetMutation }; };
  • 30.
  • 31.
    Core Foundation • CFArrayRef/ CFMutableArrayRef • CFDictionaryRef / CFMutableDictionaryRef • CFSetRef / CFMutableSetRef • CFBagRef / CFMutableBagRef • CFTreeRef • CFBinaryHeapRef
  • 32.
    Особенности CF- коллекций Особенность Способ определения CFArrayCreateMutable( kCFAllocatorDefault, Могут быть как fixed-size, так <NUMBER_OF_ITEMS>, и variable-size. &kCFTypeArrayCallBacks ); Если <NUMBER_OF_ITEMS> == 0, то variable-size CFArrayCallBacks, Поведение при CFDictionaryKeyCallBacks, добавлении/удалении/поиск CFDictionaryValueCallBacks, CFSetCallBacks, е элементов определяется CFBagCallBacks, при создании. CFTreeContext, CFBinaryHeapCallBacks/CFBinaryHeapCompareContext CFArrayRef a = (__bridge_retained CFArrayRef)[NSArray new]; CF(Mutable)ArrayRef, CFArrayRef a = (__bridge CFArrayRef)[NSArray array]; CF(Mutable)DictionaryRef, NSArray *a = (__bridge_transfer NSArray *) CFArrayCreate( 0, CF(Mutable)SetRef - toll-free (const void **) &(CFStringRef *){ bridged. CFSTR("1"), NULL Можно класть NULL или ints }, 2, с размерностью указателя. NULL );
  • 33.
    Коллекция Callback Predefined typedef struct { CFIndex version; CFArrayRetainCallBack retain; Array CFArrayReleaseCallBack release; CFArrayCopyDescriptionCallBack copyDescription; kCFTypeArrayCallBacks CFArrayEqualCallBack equal; } CFArrayCallBacks; typedef struct { // ...Like in prefixed prefixed CFDictionary CFDictionaryHashCallBack hash; kCFTypeDictionaryKeyCallBacks Dictionary } CFDictionaryKeyCallBacks; typedef struct { kCFCopyStringDictionaryKeyCallBacks kCFTypeDictionaryValueCallBacks // ...Like in array prefixed CFDictionary } CFDictionaryValueCallBacks; typedef struct { kCFTypeSetCallBacks Set/Bag // ...Like in dictionary but prefixed CFSet/CFBag } CFSet(Bag)CallBacks; kCFCopyStringSetCallBacks kCFTypeBagCallBacks kCFCopyStringBagCallBacks typedef struct { CFIndex version; Tree void *info; CFTreeRetainCallBack retain; CFTreeReleaseCallBack release; CFTreeCopyDescriptionCallBack copyDescription; } CFTreeContext; typedef struct { CFIndex version; const void *(*retain) (CFAllocatorRef allocator, const void *ptr); void (*release) Binary Heap (CFAllocatorRef allocator, const void *ptr); CFStringRef (*copyDescription)(const void *ptr); kCFStringBinaryHeapCallBacks CFComparisonResult (*compare) (const void *ptr1, const void *ptr2, void *context); } CFBinaryHeapCallBacks;
  • 34.
    Эффективность реализации Вставка Доступ Поиск worst/avg worst/avg worst/avg O(N*lg N) / CFArray O(N*lg N) / O(N) O(lg N) / O(1) < O(N*lg N) CFDictionary O(N*N) / O(1) < O(N) O(N) / O(1) CFSet O(N*N) / O(1) < O(N) O(N) / O(1) CFBag O(N*N) / O(1) < O(N) O(N) / O(1)
  • 35.
    CFTreeRef • Связь отодного parent к N children. • Parent - владелец children. У children - слабые ссылки на Parent. • Root тот, у кого нет ссылки на Parent. • Контекст, заданный при создании Node, определяет правила управления памятью и получения описания над этим Node. • Как правило, в функции работы с деревьями передается указатель на Parent Node, а операция осуществляется в отношении Child Node.
  • 36.
    CFBinaryHeap • Хранит значенияв отсортированном виде. • Любое новое значение встраивается в порядок, сохраняя сортировку. • Позволяет скорейшим образом получить минимум набора значений, но не максимум (особенности реализации). • Функция сравнения задается в поле compare в описателе при создании CFBinaryHeap. • Правила управления памятью объектов в коллекции также задаются в описателе.
  • 37.
  • 38.
    That’s all, folks! • http://opensource.apple.com/source/CF/CF-744.12/ • http://funwithobjc.tumblr.com/post/2922267976/using-custom • http://kickingbear.com/blog/archives/9 • https://github.com/nst/iOS-Runtime-Headers • Apple Documentation • Презентация на Slideshare: http://www.slideshare.net/comfly/talks-on-collections • Код на Github: https://github.com/comfly/CollectionSamples

Editor's Notes

  • #3 - Перечислить желтые - “Кроме того, &gt;&gt;&gt; NSOrderedSet, &gt;&gt;&gt; который появляется в iOS 5.
  • #4 - Core Foundation. - &gt;&gt;&gt; Новые в iOS 6 - &gt;&gt;&gt; NSPointerArray - &gt;&gt;&gt; NSMapTable - &gt;&gt;&gt; NSHashTable
  • #8 - NSArray - class-cluster. - &gt;&gt;&gt; И его иерархия примерно такова. И та не вся. - &gt;&gt;&gt; Ну а чаще всего мы встречаемся с...
  • #9 - Это лишь догадки, ибо исходников нет. - Но, что известно наверняка, что NSArray использует CFArrayRef. Это видно из исходников CoreFoundation CFArray
  • #10 Куча-куча методов с многообещающими именами - Почему Apple их не открыла - неизвестно. - Пространство имен загрязнено значительно. Хотя в дамп попадают методы категорий. - Странные методы indexOfSmallestObject. или repeatedNTimes:. firstObject, removeFirstObject.
  • #12 - NULL, fixed-size, управление через коллбеки.
  • #13 Интерфейс NSPointerArray - &gt;&gt;&gt; Управляется через NSPointerFunctionsOption, и NSPointerFunctions. О них чуть позже. - allObjects - compacting.
  • #14 NSMapTable. - (strong|weak)To(Strong|Weak)ObjectsMapTable shortcuts. - dictionaryRepresentation.
  • #15 NSHashTable - weakObjectsHashTable shortcut. - allObjects, setRepresentation.
  • #16 - первая половина - управление памятью - вторая - представление объекта, description, equality
  • #17 - работа hash и map гарантирована только при использовании этих ключей при создании.
  • #19 - Другие языки - Reflection.
  • #22 Этот набор можно дополнить своими; закономерность очевидна. Categories at your service.
  • #23 Приватность
  • #24 Предикаты раскладываются в другие предикаты и выражения. E - NSExpression P - NSPredicate A - NSArray S - NSString
  • #25 Приватность. E - NSExpression P - NSPredicate A - NSArray S - NSString
  • #26 Функции и операции, встречающиеся в formatString предикатов и выражений.