initWithFrame not executing in UIVIew - ios

I have made a UIView subclass & want to execute a method on initWithFrame:, but this method is not being called.
When I call the method from initWithCoder:, which is executing, the code crashes showing this error:
Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder requires that replaced objects be returned from initialization coder method:'
My code is:
-(void)initialize
{
//code
}
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initialize];
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if(self)
{
[self initialize];
}
return self;
}

You're not returning self from your initWithCoder: method.

Maybe you specify this UIView inside IB or storyBoard so initWithCoder is called.
Delete initWithCoder and use awakeFromNib
- (void)awakeFromNib{
//custom init code
[self initialize];
}

Try this one.
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if(self)
{
}
return self;
}

Related

How can I implement a UIViewcontroller thread safe singleton when I use storyboard?

I need that one ViewController of my app is a singleton. I'm using storyboard.
I used this code:
- (id)init
{
if (self = [super init]) {
}
return self;
}
static id s_singleton = nil;
+ (id) alloc {
if(s_singleton != nil)
return s_singleton;
return [super alloc];
}
- (id) initWithCoder:(NSCoder *)aDecoder {
if(s_singleton != nil)
return s_singleton;
self = [super initWithCoder:aDecoder];
if(self) {
s_singleton = self;
}
return self;
Maybe it is not thread safe because it creates two different instance of the class...
How can I resolve this problem?

Which init method for UIView will be called when using drag and drop in xib file

here is the custom collection view,and below label is the (rating view i design).
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initGrayStarView];
[self initYellowStarView];
[self initRatingLabel];
}
return self;
}
but i find that it every time the rating view didn't appear(image view and label did). then i found it's because that i didn't call the init method for rating view,so it's nil ,but why?
this is the init method.
but it never call it ,it only call the layoutSubview method.
Consider this sort of pattern...
-(id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self _setup];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aCoder {
if (self = [super initWithCoder:aCoder]) {
[self _setup];
}
return self;
}
-(void)_setup {
blah;
blah;
blah;
}
Try to "know what is happening" but that will get you through if you're just getting started. Hope it helps
It is in the awakeFromNib: method. Override it in your implementation file like this:
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self setupStuff];
}

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;
}

Code and encode UIView and UIViewController

Good day, everyone!
I have some view in scrollView. I want to save that views into file and then when app is open load it. So i have thias code:
-(void) encodeWithCoder:(NSCoder *)_coder{
[_coder encodeObject:self.currentForecast forKey:#"currentForecast"];
[_coder encodeObject:self.weatherForecastView forKey:#"weatherForecastView"];
[_coder encodeObject:self forKey:#"self"];
[_coder encodeObject:self.view forKey:#"view"];
}
-(id) initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
self.currentForecast = [aDecoder decodeObjectForKey:#"currentForecast"];
self.weatherForecastView = [aDecoder decodeObjectForKey:#"weatherForecastView"];
self.view = [aDecoder decodeObjectForKey:#"view"];
self = [aDecoder decodeObjectForKey:#"self"];
}
return self;
}
it works, but it looks like a screenshot of the views. How to live them up?
If it works, then why not just simplify like the following (remove the retain if you use ARC):
-(void) encodeWithCoder:(NSCoder *)_coder{
[_coder encodeObject:self forKey:#"self"];
}
-(instanceType) initWithCoder:(NSCoder *)aDecoder{
self = [[aDecoder decodeObjectForKey:#"self"] retain];
return self;
}
But I don't think it really works because using initWithCoder for self prevents calling [self init]. Or you can try:
-(instanceType) initWithCoder:(NSCoder *)aDecoder{
self = [[aDecoder decodeObjectForKey:#"self"] init];
return self;
}
But what is more common is to not encode self and that means:
-(void) encodeWithCoder:(NSCoder *)_coder{
[_coder encodeObject:self.view forKey:#"view"];
...
}
-(instanceType) initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (!self)
return nil;
self.view = [aDecoder decodeObjectForKey:#"view"];
...
return self;
}

Subclassing a UIView, one method to setup whether initWithFrame: or awakeFromNib

When subclassing a UIView I tend to create a private method called 'setup', which I put into initWithFrame and awakeFromNib.
Is this what other people tend to do too? Or is there a method I don't know about that does what I'm looking to do.
I've been through the UIView class reference but I can't see anything, so just wondered what others do?
I actually avoid using -awakeFromNib and use -initWithCoder: instead. This is my typical UIView subclass setup:
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self _init];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self _init];
}
return self;
}
- (id)init {
if (self = [super init]) {
[self _init];
}
return self;
}
- (void)_init {
}
I actually have a Snippet to do this too. I just type
init_view
And it generates all of the above.

Resources