The problem: identical method crashLog:
in multiple classes, for example
@interface ViewController : UIViewController
@end
@implementation ViewController
- (void)someMethod {
[self crashLog:@"error"];
}
-(void)crashLog:(NSString *)message {
NSLog(@"%@", message);
}
@end
Solution A: move crashLog:
to a common superclass (or a category on superclass UIViewController
)
@interface CommonViewController : UIViewController
-(void)crashLog:(NSString *)message;
@end
@implementation CommonViewController
-(void)crashLog:(NSString *)message {
NSLog(@"%@", message);
}
@end
@interface ViewController : CommonViewController
@end
@implementation ViewController
- (void)someMethod {
[self crashLog:@"error"];
}
@end
Solution B: move crashLog:
to a delegate and protocol
@protocol ICloudDBDelegate
-(void)crashLog:(NSString *)message;
@end
@interface DelegateClass : AnyClass <ICloudDBDelegate>
@end
@implementation DelegateClass
-(void)crashLog:(NSString *)message {
NSLog(@"%@", message);
}
@end
@interface ViewController : UIViewController
@end
@implementation ViewController
@property (weak, nonatomic) id <ICloudDBDelegate> iCloudDBDelegate;
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.iCloudDBDelegate = appDel.iCloudDBDelegate;
}
- (void)someMethod {
[self.iCloudDBDelegate crashLog:@"error"];
}
@end
@interface AppDelegate : UIResponder <UIApplicationDelegate, AppDelProtocolDelegate, iCloudDBDelegate>
@property (strong, nonatomic) id<iCloudDBDelegate>iCloudDBDelegate;
@end
@implementation AppDelegate
- (id<iCloudDBDelegate>)iCloudDBDelegate {
if (!_iCloudDBDelegate) {
_iCloudDBDelegate = [[DelegateClass alloc] init];
}
return _iCloudDBDelegate;
}
@end
Now we have new problem: property iCloudDBDelegate
in multiple classes
Solution B + A: move crashLog
to a delegate, move iCloudDBDelegate
property to a superclass
@protocol ICloudDBDelegate
-(void)crashLog:(NSString *)message;
@end
@interface DelegateClass : AnyClass <ICloudDBDelegate>
@end
@implementation DelegateClass
-(void)crashLog:(NSString *)message {
NSLog(@"%@", message);
}
@end
@interface CommonViewController : UIViewController
@property (weak, nonatomic) id <ICloudDBDelegate> iCloudDBDelegate;
@end
@implementation CommonViewController
@end
@interface ViewController : CommonViewController
@end
@implementation ViewController
- (void)someMethod {
[self.iCloudDBDelegate crashLog:@"error"];
}
@end
Solution C:
Another approach is a singleton object like NSUserDefaults.standardUserDefaults
or NSFontManager.sharedFontManager
: CloudDBManager.sharedCloudDBManager
. No category or protocol required, just include CloudDBManager.h and use CloudDBManager.sharedCloudDBManager
from everywhere.
@interface CloudDBManager : NSObject
@property(class, readonly, strong) CloudDBManager *sharedCloudDBManager;
-(void)crashLog:(NSString *)message;
@end
@implementation CloudDBManager
+ (CloudDBManager *)sharedCloudDBManager {
static CloudDBManager *sharedInstance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
sharedInstance = [[CloudDBManager alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
-(void)crashLog:(NSString *)message {
NSLog(@"%@", message);
}
@end
@interface ViewController : CommonViewController
@end
@implementation ViewController
- (void)someMethod {
[CloudDBManager.sharedCloudDBManager crashLog:@"error"];
}
@end