diff --git a/Code/UI/RKFetchedResultsTableController.m b/Code/UI/RKFetchedResultsTableController.m index dad10241..032d3cc0 100755 --- a/Code/UI/RKFetchedResultsTableController.m +++ b/Code/UI/RKFetchedResultsTableController.m @@ -235,7 +235,7 @@ _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest - managedObjectContext:[NSManagedObject managedObjectContext] + managedObjectContext:[NSManagedObjectContext contextForCurrentThread] sectionNameKeyPath:_sectionNameKeyPath cacheName:_cacheName]; _fetchedResultsController.delegate = self; @@ -604,16 +604,4 @@ [self didFinishLoad]; } -#pragma mark - Block setters - -// NOTE: We get crashes when relying on just the copy property. Using Block_copy ensures -// correct behavior -- (void)setOnViewForHeaderInSection:(RKFetchedResultsTableViewViewForHeaderInSectionBlock)onViewForHeaderInSection { - if (_onViewForHeaderInSection) { - Block_release(_onViewForHeaderInSection); - _onViewForHeaderInSection = nil; - } - _onViewForHeaderInSection = Block_copy(onViewForHeaderInSection); -} - @end diff --git a/Code/UI/RKForm.m b/Code/UI/RKForm.m index 347c7801..c33cfadb 100644 --- a/Code/UI/RKForm.m +++ b/Code/UI/RKForm.m @@ -158,11 +158,6 @@ [self addRowMappingAttribute:attributeKeyPath toKeyPath:cellKeyPath onCellWithClass:cellClass usingBlock:nil]; } -- (void)setOnSubmit:(RKFormBlock)onSubmit { - if (_onSubmit) Block_release(_onSubmit); - _onSubmit = Block_copy(onSubmit); -} - - (RKTableItem *)tableItemForAttribute:(NSString *)attributeKeyPath { for (RKTableItem *tableItem in self.tableItems) { if ([[tableItem.userData valueForKey:@"__RestKit__attributeKeyPath"] isEqualToString:attributeKeyPath]) { diff --git a/Code/UI/RKTableViewCellMapping.h b/Code/UI/RKTableViewCellMapping.h index 47e8c772..4ba11df3 100644 --- a/Code/UI/RKTableViewCellMapping.h +++ b/Code/UI/RKTableViewCellMapping.h @@ -23,7 +23,7 @@ /** @name Cell Mapping Block Callbacks **/ -typedef void(^RKTableViewCellForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath* indexPath); +typedef void(^RKTableViewCellForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); typedef CGFloat(^RKTableViewHeightOfCellForObjectAtIndexPathBlock)(id object, NSIndexPath *indexPath); typedef void(^RKTableViewAccessoryButtonTappedForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); typedef NSString*(^RKTableViewTitleForDeleteButtonForObjectAtIndexPathBlock)(UITableViewCell *cell, id object, NSIndexPath *indexPath); @@ -82,6 +82,17 @@ typedef void(^RKTableViewCellBlock)(UITableViewCell *cell); */ @property (nonatomic, retain) NSString* reuseIdentifier; +/** + A Boolean value that determines whether the cell mapping manages basic cell + attributes (accessoryType, selectionStyle, etc.) or defers to a Storyboard/XIB + for defining basic cell attributes. + + Setting the accessoryType or selectionStyle will set the value to YES. + + **Default**: NO + */ +@property (nonatomic, assign) BOOL managesCellAttributes; + /** The cell style to use for cells created with this mapping @@ -185,14 +196,20 @@ typedef void(^RKTableViewCellBlock)(UITableViewCell *cell); */ + (id)cellMapping; +/** + Creates and returns an RKTableCellMapping instance configured with the default cell mappings. + + @return An RKTableCellMapping instance with default mappings applied. + @see [RKTableCellMapping addDefaultMappings] + */ ++ (id)defaultCellMapping; + /** Returns a new auto-released object mapping targeting UITableViewCell. The mapping will be yielded to the block for configuration. */ + (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping *cellMapping))block; -// TODO: Needs NIB support... - /** Sets up default mappings connecting common properties to their UITableViewCell counterparts as follows: diff --git a/Code/UI/RKTableViewCellMapping.m b/Code/UI/RKTableViewCellMapping.m index 48c89bfe..a04469e7 100644 --- a/Code/UI/RKTableViewCellMapping.m +++ b/Code/UI/RKTableViewCellMapping.m @@ -93,13 +93,18 @@ typedef void(^RKControlBlockActionBlock)(id sender); @synthesize targetIndexPathForMove = _targetIndexPathForMove; @synthesize rowHeight = _rowHeight; @synthesize deselectsRowOnSelection = _deselectsRowOnSelection; - -// TODO: Figure out nib support... +@synthesize managesCellAttributes; + (id)cellMapping { return [self mappingForClass:[UITableViewCell class]]; } ++ (id)defaultCellMapping { + RKTableViewCellMapping *cellMapping = [self cellMapping]; + [cellMapping addDefaultMappings]; + return cellMapping; +} + + (id)cellMappingUsingBlock:(void (^)(RKTableViewCellMapping*))block { RKTableViewCellMapping* cellMapping = [self cellMapping]; block(cellMapping); @@ -111,9 +116,10 @@ typedef void(^RKControlBlockActionBlock)(id sender); if (self) { self.cellClass = [UITableViewCell class]; self.style = UITableViewCellStyleDefault; - self.accessoryType = UITableViewCellAccessoryNone; - self.selectionStyle = UITableViewCellSelectionStyleBlue; - self.rowHeight = 44; // TODO: Should row height be an informal protocol on cells??? + self.managesCellAttributes = NO; + _accessoryType = UITableViewCellAccessoryNone; + _selectionStyle = UITableViewCellSelectionStyleBlue; + self.rowHeight = 44; self.deselectsRowOnSelection = YES; _prepareCellBlocks = [NSMutableArray new]; } @@ -161,35 +167,48 @@ typedef void(^RKControlBlockActionBlock)(id sender); copy.targetIndexPathForMove = self.targetIndexPathForMove; copy.rowHeight = self.rowHeight; - for (NSValue *blockValue in [self prepareCellBlocks]) { - [copy addPrepareCellBlock:[blockValue pointerValue]]; + @synchronized(_prepareCellBlocks) { + for (void (^block)(UITableViewCell *) in _prepareCellBlocks) { + [copy addPrepareCellBlock:[block copy]]; + } } return copy; } -- (id)mappableObjectForData:(UITableView*)tableView { +- (id)mappableObjectForData:(UITableView *)tableView { NSAssert([tableView isKindOfClass:[UITableView class]], @"Expected to be invoked with a tableView as the data. Got %@", tableView); - // TODO: Support for non-dequeueable cells??? RKLogTrace(@"About to dequeue reusable cell using self.reuseIdentifier=%@", self.reuseIdentifier); UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier]; if (! cell) { cell = [[[self.objectClass alloc] initWithStyle:self.style reuseIdentifier:self.reuseIdentifier] autorelease]; } - cell.accessoryType = self.accessoryType; - cell.selectionStyle = self.selectionStyle; + + if (self.managesCellAttributes) { + cell.accessoryType = self.accessoryType; + cell.selectionStyle = self.selectionStyle; + } // Fire the prepare callbacks - for (NSValue *value in _prepareCellBlocks) { - __block void (^prepareCellBlock)(id sender) = [value pointerValue]; - prepareCellBlock(cell); + for (void (^block)(UITableViewCell *) in _prepareCellBlocks) { + block(cell); } return cell; } +- (void)setSelectionStyle:(UITableViewCellSelectionStyle)selectionStyle { + self.managesCellAttributes = YES; + _selectionStyle = selectionStyle; +} + +- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType { + self.managesCellAttributes = YES; + _accessoryType = accessoryType; +} + - (void)setObjectClass:(Class)objectClass { NSAssert([objectClass isSubclassOfClass:[UITableViewCell class]], @"Cell mappings can only target classes that inherit from UITableViewCell"); [super setObjectClass:objectClass]; @@ -218,10 +237,7 @@ typedef void(^RKControlBlockActionBlock)(id sender); #pragma mark - Control Action Helpers - (void)addPrepareCellBlock:(void (^)(UITableViewCell *cell))block { - NSValue *value = [NSValue valueWithPointer:Block_copy(block)]; - [_prepareCellBlocks addObject:value]; - // TODO: WTF? We can't use blocks naturally... -// [_prepareCellBlocks addObject:Block_copy(block)]; + [_prepareCellBlocks addObject:[block copy]]; } - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents toControlAtKeyPath:(NSString *)keyPath { @@ -255,73 +271,4 @@ typedef void(^RKControlBlockActionBlock)(id sender); [self addBlockAction:block forControlEvents:UIControlEventTouchUpInside toControlAtKeyPath:keyPath]; } -#pragma mark - Block setters - -// NOTE: We get crashes when relying on just the copy property. Using Block_copy ensures -// correct behavior - -- (void)setOnSelectCell:(RKTableViewAnonymousBlock)onSelectCell { - if (_onSelectCell) { - Block_release(_onSelectCell); - _onSelectCell = nil; - } - _onSelectCell = Block_copy(onSelectCell); -} - -- (void)setOnSelectCellForObjectAtIndexPath:(RKTableViewCellForObjectAtIndexPathBlock)onSelectCellForObjectAtIndexPath { - if (_onSelectCellForObjectAtIndexPath) { - Block_release(_onSelectCellForObjectAtIndexPath); - _onSelectCellForObjectAtIndexPath = nil; - } - _onSelectCellForObjectAtIndexPath = Block_copy(onSelectCellForObjectAtIndexPath); -} - -- (void)setOnCellWillAppearForObjectAtIndexPath:(RKTableViewCellForObjectAtIndexPathBlock)onCellWillAppearForObjectAtIndexPath { - if (_onCellWillAppearForObjectAtIndexPath) { - Block_release(_onCellWillAppearForObjectAtIndexPath); - _onCellWillAppearForObjectAtIndexPath = nil; - } - _onCellWillAppearForObjectAtIndexPath = Block_copy(onCellWillAppearForObjectAtIndexPath); -} - -- (void)setHeightOfCellForObjectAtIndexPath:(RKTableViewHeightOfCellForObjectAtIndexPathBlock)heightOfCellForObjectAtIndexPath { - if (_heightOfCellForObjectAtIndexPath) { - Block_release(_heightOfCellForObjectAtIndexPath); - _heightOfCellForObjectAtIndexPath = nil; - } - _heightOfCellForObjectAtIndexPath = Block_copy(heightOfCellForObjectAtIndexPath); -} - -- (void)setOnTapAccessoryButtonForObjectAtIndexPath:(RKTableViewAccessoryButtonTappedForObjectAtIndexPathBlock)onTapAccessoryButtonForObjectAtIndexPath { - if (_onTapAccessoryButtonForObjectAtIndexPath) { - Block_release(_onTapAccessoryButtonForObjectAtIndexPath); - _onTapAccessoryButtonForObjectAtIndexPath = nil; - } - _onTapAccessoryButtonForObjectAtIndexPath = Block_copy(onTapAccessoryButtonForObjectAtIndexPath); -} - -- (void)setTitleForDeleteButtonForObjectAtIndexPath:(RKTableViewTitleForDeleteButtonForObjectAtIndexPathBlock)titleForDeleteButtonForObjectAtIndexPath { - if (_titleForDeleteButtonForObjectAtIndexPath) { - Block_release(_titleForDeleteButtonForObjectAtIndexPath); - _titleForDeleteButtonForObjectAtIndexPath = nil; - } - _titleForDeleteButtonForObjectAtIndexPath = Block_copy(titleForDeleteButtonForObjectAtIndexPath); -} - -- (void)setEditingStyleForObjectAtIndexPath:(RKTableViewEditingStyleForObjectAtIndexPathBlock)editingStyleForObjectAtIndexPath { - if (_editingStyleForObjectAtIndexPath) { - Block_release(_editingStyleForObjectAtIndexPath); - _editingStyleForObjectAtIndexPath = nil; - } - _editingStyleForObjectAtIndexPath = Block_copy(editingStyleForObjectAtIndexPath); -} - -- (void)setTargetIndexPathForMove:(RKTableViewTargetIndexPathForMoveBlock)targetIndexPathForMove { - if (_targetIndexPathForMove) { - Block_release(_targetIndexPathForMove); - _targetIndexPathForMove = nil; - } - _targetIndexPathForMove = Block_copy(targetIndexPathForMove); -} - @end