In Objective-C I had a piece of code that would call an operation on an array of objects that contained strings. Each string-containing object would report back if a change occurred. And each object that reported a change had to be reported in a notification.
This is the Objective-C code:
-(void)forAllObjectsDo:(SEL)method {
// The line numbers that are send with the notification (if any)
NSMutableArray* arr = [[NSMutableArray alloc] init];
// For all objects do
for (int i=0; i<[datamodel count]; i++) {
// Get the object to process
BRObject* obj = [datamodel objAtIndex:i];
// Does the object respond to the given selector?
if ([obj respondsToSelector:method]) {
// Supress the "leak" warning, we don't want unneccessary warnings.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// The object implements the selector, call the selector and
// check if the object was changed
if ([obj performSelector:method]) {
// Something changed.
// Add this line to de notification info.
[arr addObject:[NSNumber numberWithInt:i]];
}
// Restore the old diagnostics
#pragma clang diagnostic pop
}
}
// If there are changes, post the notification
if ([arr count] > 0) {
// Generate and send a notification
NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys:arr, UPDATED_OBJECTS_KEY, nil];
[[NSNotificationCenter defaultCenter] postNotificationName:OBJECTS_UPDATED_NOTIFICATION
object:self
userInfo:dict];
}
}
private func forAllObjectsDo(closure: (Int) -> Bool) {
var arr: Array<Int> = []
for i in 0 ..< dataModel.objects.count {
if closure(i) { arr.append(i) }
}
fireViewUpdatedNotificationIfNotEmpty(arr)
}
private func fireViewUpdatedNotificationIfNotEmpty(arr: Array<Int>) {
if arr.count > 0 {
let dict = [UPDATED_OBJECTS_KEY: arr]
NSNotificationCenter.defaultCenter().postNotificationName(OBJECT_UPDATED_NOTIFICATION, object:self, userInfo:dict)
}
}
[self forAllObjectsDo:@selector(deleteHalf)];
The Swift code is called like this:
forAllObjectsDo({ [unowned self] (i) in return self.datamodel.objAtIndex(i).deleteHalf() })
All in al the new way is much better looking than the old way. And once I grokked the usage of closures, it seems silly that it was so hard to do before. The key was to realise that the old code cannot be replaced 1 to 1 with new code. As you can see above the separation is slightly different. In Objective-C I could iterate over the objects and call the selector, in the Swift code I have to include the selection of the object to call into the closure.
Happy coding...
Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH
We don't get the world we wish for... we get the world we pay for.
No comments:
Post a Comment