Last active
October 4, 2018 08:37
-
-
Save dodikk/4a0f1d98faa7c1336551 to your computer and use it in GitHub Desktop.
Objective-C++ cast templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender | |
{ | |
if ([segueId isEqualToString:@"seagueAppointmentListToMap"]) | |
{ | |
HLJAppointment* appointment = objc_kind_of_cast<HLJAppointment>(sender); | |
HLJAppointmentMapController *controller = objc_member_of_cast<HLJAppointmentMapController>(destinationController); | |
// property injection | |
controller.model = appointment; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define KINDOF_CAST(arg) ((__kindof typeof(arg))(arg)) | |
// USAGE : | |
// | |
// | |
void example() | |
{ | |
UICollectionViewFlowLayout* flowLayout = KINDOF_CAST(self.collectionView.collectionViewLayout); | |
} | |
// reasoning | |
// | |
// The macro works at compile time | |
// it relies on the `collectionViewLayout` declaration type | |
// so the expression results in | |
// | |
// UICollectionViewFlowLayout* flowLayout = (__kindof UICollectionViewLayout)(self.collectionView.collectionViewLayout); | |
// The `__kindof UICollectionViewLayout` type silences the compiler's "type mismatch" warnings | |
// because `UICollectionViewFlowLayout` is a child of `UICollectionViewLayout` | |
// | |
// At runtime it's better to use one of the templates above | |
// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __JFF_CAST_FUNCTIONS_H__ | |
#define __JFF_CAST_FUNCTIONS_H__ | |
#import <Foundation/Foundation.h> | |
template < class DESTINATION > | |
DESTINATION* objc_kind_of_cast(id nsObject) | |
{ | |
if (nil == nsObject) { | |
return nil; | |
} | |
Class destinationClass = [DESTINATION class]; | |
if (![nsObject isKindOfClass:destinationClass]) { | |
return nil; | |
} | |
return (DESTINATION *)nsObject; | |
} | |
template < class DESTINATION > | |
DESTINATION* objc_member_of_cast(id nsObject) | |
{ | |
if (nil == nsObject) { | |
return nil; | |
} | |
Class destinationClass = [DESTINATION class]; | |
if (![nsObject isMemberOfClass:destinationClass]) { | |
return nil; | |
} | |
return (DESTINATION*)nsObject; | |
} | |
template < class DESTINATION > | |
DESTINATION* objc_dynamic_cast(id nsObject) | |
{ | |
return objc_kind_of_cast<DESTINATION>(nsObject); | |
} | |
template < class DESTINATION > | |
DESTINATION *objc_reinterpret_cast(id nsObject) | |
{ | |
return (DESTINATION *)nsObject; | |
} | |
#endif //__JFF_CAST_FUNCTIONS_H__ |
Reasoning behind the macro
#define KINDOF_CAST(arg) ((__kindof typeof(arg))(arg))
UICollectionViewFlowLayout* flowLayout = KINDOF_CAST(self.collectionView.collectionViewLayout);
The macro works at compile time. It relies on the collectionViewLayout
property declaration type.
So the expression results in
UICollectionViewFlowLayout* flowLayout = (__kindof UICollectionViewLayout)(self.collectionView.collectionViewLayout);
The __kindof UICollectionViewLayout
type silences the compiler's "type mismatch" warnings because UICollectionViewFlowLayout
is a child of UICollectionViewLayout
.
The templates above do the runtime checks so these casts might co-exist depending on the "safety" level chosen by the programmer.
A separate gist for the compile time __kindof
based cast
https://gist.github.com/dodikk/16d4e7b4ef6cb0cf98cd2dac44e13003
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO: add a modern macro with typeof and kindof
By Scherbinin Anatoly from the cocoa chat ("Какао-чат: Cocoa, Xcode, objective C")