Object-c How to call father method in father when being subclass - ios

#interface Father : NSObject
-(void)show;
#end
#interface Child : Father
-(void)show;
#end
- (instancetype)init
{
self = [super init];
[self show];
return self;
}
- (void)show
{
NSLog(#"I am father");
}
#end
#implementation Child
- (instancetype)init
{
self = [super init];
[self show];
return self;
}
- (void)show
{
NSLog(#"I am child");
}
#end
- (void)viewDidLoad
{
Child *child = [[Child alloc] init];
}
Output:
I am child
I am child
From the code and output, we can see [self show] in father actually call [child show]. Is there a way to call father method in father when the method is overridden by child, In other words, Is there a way to choose to father method or child method.

#implementation Child
- (instancetype)init
{
self = [super init];
[self show];
return self;
}
- (void)show
{
NSLog(#"I am child");
[super show]; // This line call show method of father class
}
#end
- (void)viewDidLoad
{
Child *child = [[Child alloc] init];
}
Try above code.
Go through Objective-C doc https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html

You Can Call Super class methods using
[super show]; //call this method from within child class
This method execution, calls the show method in Super Class(Father Class In our Case)
Hope this helps

Related

Initializing a UIViewController correctly and passing in properties

I have a UIViewController called TestViewController.h/.m:
Header file has:
#property (nonatomic, assign) BOOL isTested;
Implementation file has:
#implementation TestViewController
- (void)viewDidLoad
{
if (_isTested)
{
[self postNotification];
[self listenToNotifications];
}
}
I have a view that has this:
- (void) replyTapPressed
{
TestViewController *test = [[TestViewController alloc] init];
test.isTested = NO;
[_parent.navigationController pushViewController:test animated:YES];
}
Through the app's life cycle, the TestViewController's property starts off as YES; but when the view about gets called, it should set the property to NO; - which it does.
But _parent (which is the parent UIViewController) and test are both NULL.
Am I initializing and implementing it wrong?
Thanks.
You may try in below ways -
TestViewController.m
- (id)initWithTested:(BOOL)value
{
if (self = [super init])
{
self.isTested = value;
}
return self;
}
- (void) replyTapPressed
{
TestViewController *test = [[TestViewController alloc] initWithTested:NO];
[_parent.navigationController pushViewController:test animated:YES];
}
The view will "load" during initialization of your controller. To achieve what you want, implement viewWillAppear and move
if (_isTested) {
[self postNotification];
[self listenToNotifications];
}
there. (You could also put this in viewDidAppear, depending on what you are doing.)

Simple custom delegate not getting called

Let's see if you guys can find the error here... because I'm really stuck right now.
DBManager.h
#protocol DBManagerDelegate <NSObject>
#optional
- (void) managerDidFinishUpdating:(id)controller;
#end
#interface DBManager : NSObject
#property (strong, nonatomic) id <DBManagerDelegate> delegate;
- (id) init;
#end
DBManager.m
#import "DBManager.h"
#implementation DBManager
- (id)init {
self = [super init];
if (self) {
[[self delegate] managerDidFinishUpdating:self];
}
return self;
}
UIViewController.h
#import <UIKit/UIKit.h>
#import "DBManager.h"
#interface DBViewController : UIViewController <DBManagerDelegate>
#property (nonatomic, retain) DBManager *manager;
#end
UIViewController.m
#import "DBViewController.h"
#implementation DBViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_manager = [[DBMataroManager alloc] init];
[_manager setDelegate:self];
}
- (void)managerDidFinishUpdating:(id)controller {
NSLog(#"Manager did finish");
}
#end
You should write like this,
- (id)initWithDelegate:(id)delegate {
self = [super init];
if (self) {
_delegate = delegate;
[_delegate managerDidFinishUpdating:self];
}
return self;
}
//Call it as follow
_manager = [[DBManager alloc] initWithDelegate:self];
[_manager setDelegate:self];
The delegate method managerDidFinishUpdating: is called within init. You set yourself as the delegate after calling init.
Maybe an initWithDelegate: method would help.
- (instancetype)initWithDelegate:(id< DBManagerDelegate>)delegate {
self = [super init];
if (self) {
self.delegate = delegate;
[self.delegate managerDidFinishUpdating:self];
}
return self;
}
You are trying to use the delegate in the init, but you have not set it until the next statement. The only way to do this would be to set the delegate as part of you init statement.
-(id)initWithDelegate:(id<DBManageDelegate>)delegate {
if ((self = [super init])) {
self.delegate = delegate;
if (delegate && [delegate respondsToSelector:#selector(managerDidFinishUpdating:)]) {
[delegate performSelector:#selector(managerDidFinishUpdating:) withObject:self];
}
}
return self;
}
But if you plan to do some additional things before the manager is updated I would suggest you move all of that outside of the init, perhaps into an updateManager function like this
-(void)updateManager {
// Do the stuff that updates your manager here
if (delegate && [delegate respondsToSelector:#selector(managerDidFinishUpdating:)]) {
[delegate performSelector:#selector(managerDidFinishUpdating:) withObject:self];
}
}
..later in your app
_manager = [[DBMataroManager alloc] init];
[_manager setDelegate:self];
[_manager updateManager];

objective C [self init] hierarchy for multilevel inheritance

I have class A which inherits class B. And want to achieve something like below. But the init methods get recursive call due to dynamic typecasting.
Is there any way to achieve such? Any suggestion? (without changing 'init's name in subclass?
#interface A : NSObject
#property NSData * data;
#end
#implementation A
- (id) init {
self = [super init];
/* want to do some default initialization here
for this class and all of its subclasses. */
// ... ...
return self;
}
/* This [self init] get recursed.
But how can I force this class and all of its subclass to call [self init] above,
not to call the subclass's init method. */
- (id) initWithData:(NSData *)d {
self = [self init];
self.data = d;
return self;
}
#end
#interface B : A
#end
#import "B.h"
#implementation B
- (id) init {
self = [super initWithData:nil];
// some subclass specific init code here ...
return
}
#end
Using B,
- (void) testInit{
B * b = [[B alloc] init];
}
You're calling [self init] in your implementation which is causing the recursion issue..
Implement this way :
- (id) init {
self = [super init];
//Basic empty init...
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init]; //<---- check this line.
if(self)
{
self.data = d;
}
return self;
}
//If you are looking to write some init code only 1 time the the following can work.....
-(void)oneTimeWrittenInitCode:(id)mySelf
{
//your init code which you wish to write one time goes here...
}
- (id) init {
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
}
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
self.data = d;
}
return self;
}
Look up the "designated initializer" pattern. It describes how to arrange initializer methods and convenience constructors (a.k.a. factory methods) in a class hierarchy.
Here is an example of designated initilizer pattern mentioned above,
#import ”Person.h”
#implementation Person
-(id) initWithAge:(int)theAge AndHeight:(int)theHeight AndName:(NSString *)theName {
if (self = [super init]){
_age = theAge;
_height = thefleight;
_name = theName;
}
return self;
}
-(id) initwithAge:(int)theAge AndHeight:(int)theHeight {
return [self initWithAge:theAge AndHeight:theHeight AndName:nil];
}
-(id) initwithAge:(int)theAge {
return [self initWithAge:theAge AndHeight:0];
}
- (id)init {
return [self initwithAge:0];
}
#end
It should be:
- (instancetype) initWithData:(NSData *)d
{
if(self = [super init])
{
_data = d;
}
return self;
}

Push ViewController

I have added UINavigationBar in appDelegate method. Please check my atatched screen shots. In bottom is i have used UINavigationBar. In middel of the page history button is there.
Here when i click the history button its cant go to historyviwcontrooler. Because i cant push the view. Can you please tell me how i can push here. When i click history its called only one calls after only thet called another class there only i given UI. How i handel here . please help me
#import "UICallButton.h"
#import "LinphoneManager.h"
#import <CoreTelephony/CTCallCenter.h>
#implementation UICallButton
#synthesize addressField;
#pragma mark - Lifecycle Functions
- (void)initUICallButton {
[self addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
}
- (id)init {
self = [super init];
if (self) {
[self initUICallButton];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initUICallButton];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
[self initUICallButton];
}
return self;
}
- (void)dealloc {
[addressField release];
[super dealloc];
}
#pragma mark -
- (void)touchUp:(id) sender {
NSString *address = [addressField text];
NSString *displayName = nil;
ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:address];
if(contact) {
displayName = [FastAddressBook getContactDisplayName:contact];
}
[[LinphoneManager instance] call:address displayName:displayName transfer:FALSE];
}
#end
Basically, you must have a UINavigationController, and not just a UINavigationBar, in order to be able to perform a push transition to one UIViewController to another.
I'm not explaining how to do that because it's very basic, you should study and read some books/tutorials before begin a real project.
Here's some links to help you:
A nice tutorial
How to use navigation controllers (from apple)
Navigation Controller class reference

Keeps giving me incorrect implementation with my singleton

I decided to try and make a Singleton for use with locations. I have got what I think to be, the singleton working correctly however I have one error that is now appearing. It tells me that my implementation is incomplete. It is the only error it is giving me and I am sure it is something wrong with either my view header or m file. I have tried a few things now and cannot get it to work. What am I missing here?
Here is my header
#import <UIKit/UIKit.h>
#interface TrackerViewController : UIViewController
-(void) locationUpdate;
end
And here is my implementation file:
#import "TrackerViewController.h"
#import "MyLocation.h"
#implementation TrackerViewController
NSString *LatCoord;
NSString *LongCoord;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[LocationController sharedInstance].locDelegate = (id)self;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)locationUpdate:(CLLocation *)location {
[[LocationController sharedInstance] setLocation:location];
LatCoord = [NSString stringWithFormat:#"%lf", location.coordinate.latitude];
LongCoord = [NSString stringWithFormat:#"%lf", location.coordinate.longitude];
}
- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(IBAction)CheckIn:(id)sender
{
[self locationUpdate];
}
#end
My singleton header is as follows:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol LocationControllerDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation*)location;
#end
#interface LocationController : NSObject <CLLocationManagerDelegate> {
__unsafe_unretained id <LocationControllerDelegate> _locDelegate;
CLLocationManager* locationManager;
CLLocation* location;
id locDelegate;
}
#property (nonatomic, retain) CLLocationManager* locationManager;
#property (nonatomic, retain) CLLocation* location;
#property (nonatomic, assign) id <LocationControllerDelegate> locDelegate;
+ (LocationController*)sharedInstance;
#end
My singleton implementation is as follows:
#import "MyLocation.h"
static LocationController* sharedCLDelegate = nil;
#implementation LocationController
#synthesize locationManager, location, locDelegate = _locDelegate;
- (id)init
{
self = [super init];
if (self != nil) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return self;
}
- (void)dealloc
{
/* ... */
}
#pragma mark -
#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager*)manager
didUpdateToLocation:(CLLocation*)newLocation
fromLocation:(CLLocation*)oldLocation
{
/* ... */
}
- (void)locationManager:(CLLocationManager*)manager
didFailWithError:(NSError*)error
{
/* ... */
}
#pragma mark -
#pragma mark Singleton Object Methods
+ (LocationController*)sharedInstance {
#synchronized(self) {
if (sharedCLDelegate == nil) {
}
}
return sharedCLDelegate;
}
+ (id)allocWithZone:(NSZone *)zone {
#synchronized(self) {
if (sharedCLDelegate == nil) {
sharedCLDelegate = [super allocWithZone:zone];
return sharedCLDelegate;
}
}
return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
#end
What am I missing or doing wrong here?
I think the root of the problem is here:
#protocol LocationControllerDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation*)location;
#end
So you've defined a protocol with a required method, but unless I've missed it you haven't implemented that method anywhere in the object that adopts that protocol. The compiler is warning you that you haven't implemented all the required methods of the protocol.
Your singleton looks wrong. Your sharedInstance method should be:
+ (LocationController*)sharedInstance {
#synchronized(self) {
if (sharedCLDelegate == nil) {
sharedCLDelegate = [[self alloc] init];
}
}
return sharedCLDelegate;
}
And you can get rid of the allocWithZone: and copyWithZone: methods - they don't do anything useful.
That's most likely why your class isn't working, but probably has nothing to do with the "incomplete implementation" warning. The warning will be because you've forgotten to implement a method that's declared in your header or in one of your protocols, or maybe you've misspelled it. I couldn't spot it on a first pass, but I'll take another look.
If you double-click on the yellow warning icon in the header it should tell you which method hasn't been implemented properly.
By the way, the line below leaks because you're double-retaining (init sets retain count to one, and then assigning to a retained property sets it to 2). You should run the Analyze function, which will add blue warnings for leaks like this.
self.locationManager = [[CLLocationManager alloc] init];
Do one of the following instead:
//assign directly to the ivar so the setter method isn't used
locationManager = [[CLLocationManager alloc] init];
Or
//autorelease before assigning
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationUpdate is declared in your interface, but not defined in the implementation. locationUpdate: is defined -- close, but not quite.
Note: The message could have saved some time.

Resources