Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
#import <Foundation/Foundation.h>
#include <stdio.h>
@interface NSString (MyPrintable)
- (const char *)toCString;
@implementation NSString (MyPrintable)
// NSString is a library provided class that doesn't have
// a toCString method. We're dynamically extending the class
// below adding the method to every class instance.
- (const char *)toCString {
return [self cStringUsingEncoding: NSASCIIStringEncoding];
@interface NSNumber (MyPrintable)
- (const char *)toCString;
@implementation NSNumber (MyPrintable)
// stringValue is a library provided method of NSNumber
// that returns NSString. We're dynamically extending
// NSNumber here with a new toCString method making
// use of the toCString we just added to NSString.
- (const char *)toCString {
return [[self stringValue] toCString];
int main() {
// The array below contains instances of classes
// NSString, NSNumber, NSString, and NSNumber in order.
NSArray *list = @[@"3.14", @4.5, @"5", @6];
// NSString type annotation below is only used as a request
// to the compiler to check if the str variable is used
// as an instance of NSString, for instance, that only
// methods present in the NSString class are called.
// The compiler doesn't check that str actually is an
// NSString, and in fact, it's not as half of the time
// it's NSNumber. There will be neither warning nor error
// from the compiler here.
for (NSString *str in list)
printf("%s\n", [str toCString]);
int sum = 0;
for (NSNumber *num in list)
sum += [num intValue];
printf("%d\n", sum);
// The program successfully outputs the following:
// 3.14
// 4.5
// 5
// 6
// 18
// It's perfectly correct, there is no undefined
// behavior, no memory leaks or any other issues.
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment