; - (instancetype)initWithFrame:(CGRect)frame; //使用xib创建或者用拖控件的方式创建自定义View对象,会调用到重写的- (instancetype)initWithCoder :(NSCoder *)aDecoder; - (instancetype)initWithCoder:(NSCoder *)aDecoder; 举例: - (instancetype)init{ :(NSCoder *)aDecoder{ NSLog(@"initWithCoder ... 111 "); if (self = [super initWithCoder: aDecoder]){ NSLog(@"initWithCoder ... 222 "); } return self; } /* 1、纯代码创建该自定义对象 a)、 总结:使用xib或拖控件的方式都会调用initWithCoder构造方法 */
initWithFrame:(CGRect)frame]; NSLog(@"%s", __func__); return self; } -(instancetype)initWithCoder :(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; NSLog(@"%s", __func__) NSBundle *)nibBundleOrNil]; NSLog(@"%s", __func__); return self; } -(instancetype)initWithCoder :(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; NSLog(@"%s", __func__) NSBundle mainBundle]loadNibNamed:@"YFView" owner:nil options:nil];[array lastObject];那么它的生命周期为: -[YFView initWithCoder
方法 - (instancetype)initWithCoder:(NSCoder *)aDecoder复制代码 需要在对应的这两个方法里面去加上bundle的方法。 如果你在Designables 那里把Debug打开,然后断点打到initWithCoder 和 initWithFrame那里,会发现程序总是运行到这一行 self = [super initWithCoder log,可以看到,initWithCoder以后,会按照以下的路线去调用. :]——[BottomCommentView initWithCoder:] 从NSBundle加载开始,解析完之后会调用到ClassSwapper 的initWithCoder,由于我们class写了自己 经过上面的分析之后,我们就知道了问题就出在我们在initWithCoder里面又调用了loadNibName,loadNibName又会去最终调UIClassSwapper initWithCoder。
name"]; 解档调用 一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量 - (nullable instancetype)initWithCoder :(NSCoder *)aDecoder; self.name = [decoder decodeObjectForKey:@"name"]; initWithCoder原理:只要解析文件就会调用,xib ,storyboard都是文件,因此只要解析这两个文件,就会调用initWithCoder,因此如果在storyboard使用自定义view,重写initWithCoder方法,一定要调用[super initWithCoder:],因为只有系统才知道怎么解析storyboard,如果没有调用,就解析不了这个文件。 :方法中加上一句self = [super initWithCoder:decoder];确保继承的实例变量也能被解码,即也能被恢复 4、多个对象归档解档 使用archiveRootObject:toFile
(如: UIView的initWithCoder调用的是NSObject的init) 确保充分覆盖所有继承的初始化 4.多个指定初始化方法: 当某对象的实例有两种完全不同的创建方式时,必须分开处理时,会出现这种情况 return [self initWithWidth:5.0 height:5.0]; } #pragma mark - Designated Initializer - (instancetype)initWithCoder :(NSCoder *)coder { self = [super initWithCoder:coder]; // 调用父类相关DI if (self) { // 再执行本类相关任务 :(NSCoder *)coder { self = [super initWithCoder:coder]; // 如果没有调用父类的同名方法,而是 自己的初始化方法/超类的其他初始化方法 // 那么Rectangle类的initWithCoder:就没机会执行了(就无法将_width和_height这俩实例变量解码了) if (self) { // Square's specific
NSString *name; // 协议里面的方法: - (void)encodeWithCoder:(NSCoder *)aCoder; // 归档 - (nullable instancetype)initWithCoder NSCoder *)aCoder { [aCoder encodeObject:_name forKey:@"name"]; } // 读取name属性并赋值 - (instancetype)initWithCoder stringByAppendingPathComponent:@"person.data"]; [NSKeyedArchiver archiveRootObject:p toFile:filePath]; 解档:(必须实现initWithCoder
最近项目需要缓存,因为项目都是用的对象,要缓存对象必须实现NSCoding协议,但是每个Model都要实现 - (void)encodeWithCoder:(NSCoder*)aCoder - (id)initWithCoder 实现的思路写一个BaseModel,在BaseModel里实现 - (void)encodeWithCoder:(NSCoder*)aCoder - (id)initWithCoder:(NSCoder
=== @interface State : NSObject<ActionProtocol> { @protected Coder *_coder; } - (instancetype)initWithCoder coder; @end //================== State.m ================== @implementation State - (instancetype)initWithCoder instancetype)init{ self = [super init]; if (self) { _stateAwake = [[StateAwake alloc] initWithCoder :self]; _stateCoding = [[StateCoding alloc] initWithCoder:self]; _stateEating = [[StateEating alloc] initWithCoder:self]; _stateSleeping = [[StateSleeping alloc] initWithCoder:self];
将PaymentModel类型变成NSData类型就必须实现归档,在PaymentModel.h文件中遵守NSCoding协议,在PaymentModel.m文件中实现encodeWithCoder和initWithCoder encodeObject:self.title forKey:@"title"]; [aCoder encodeObject:self.picture forKey:@"picture"]; } - (id)initWithCoder
- (void)encodeWithCoder:(NSCoder *)aCoder; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder brand"]; [aCoder encodeObject:_version forKey:@"version"]; } 接下来是解档的协议方法实现 - (nullable instancetype)initWithCoder 即 [super encodeWithCoder:aCoder] 和[super initWithCoder:aDecoder] 方法 使用 : 因为之前我提过 我们要存储一个数组,那么我们可以把数组中的数据转化成
NSCoding> @property (nonatomic, copy) NSString *age; @property (nonatomic, copy) NSString *name; - (id)initWithCoder :(NSCoder *)coder; - (void)encodeWithCoder:(NSCoder *)coder; @implementation Person - (id)initWithCoder
super initWithFrame:frame]) { NSLog(@"%s",__func__); } return self; } - (instancetype)initWithCoder :(NSCoder *)aDecoder{ if (self = [super initWithCoder:aDecoder]) { } NSLog(@"%s",__func 通过加载xib方法初始化自定义控件log打印 代码实验结论: 通过代码初始化自定义控件是不会自动加载xib的,它会执行initWithFrame和init 通过加载xib初始化自定义控件,仅仅执行 initWithCoder
解决办法二 自定义一个颜色值对应的UILabel #import "UILabel_13234C.h" @implementation UILabel_13234C - (instancetype)initWithCoder :(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self initTextColor
-(id)initWithCoder:(NSCoder *)aDecoder { if ((self = [super initWithCoder:aDecoder])) { NSArray arrayContentView objectAtIndex:0]; [self addSubview:rightView]; } return self; } 由于我用的是xib,所以初始化方法为initWithCoder
description - (void)encodeWithCoder:(NSCoder *)aCoder { [self yy_modelEncodeWithCoder:aCoder]; } - (id)initWithCoder modelDescription];\}\- (void)encodeWithCoder:(NSCoder *)aCoder {\ [self modelEncodeWithCoder:aCoder];\}\- (id)initWithCoder
nibNameOrNil bundle:nibBundleOrNil]) { } return self; } // storyBoard走这个方法 - (instancetype)initWithCoder :(NSCoder *)aDecoder { NSLog(@"%s", __FUNCTION__); if (self = [super initWithCoder:aDecoder] initWithCoder: 如果使用StoryBoard进行视图管理,程序不会直接初始化一个UIViewController,StoryBoard会自动初始化或在segue被触发时自动初始化,因此方法 initWithNibName:bundle不会被调用,但是initWithCoder会被调用。 :(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { NSLog(@"%s",__func__)
aCoder encodeInt:_age forKey:kage]; [aCoder encodeObject:_others forKey:kothers]; } - (instancetype)initWithCoder DWPerson.m中取代之前的代码 - (void)encodeWithCoder:(NSCoder *)aCoder { [self encode:aCoder]; } - (instancetype)initWithCoder Archive_h #import "NSObject+ArchiveExtension.h" #define ArchiveImplemention \ \ - (instancetype)initWithCoder
只需在自定义类中重写方法: (void)encodeWithCoder:(NSCoder*)aCoder { [self yy_modelEncodeWithCoder:aCoder]; } (id)initWithCoder
encodeObject:_name forKey:@"name"]; [aCoder encodeObject:_age forKey:@"age"]; } - (instancetype)initWithCoder [aCoder encodeObject:[self valueForKey:key] forKey:key]; } } - (nullable instancetype)initWithCoder
将数据解码并创建一个对象 反序列化时调用该方法,在该方法中反序列化对象的每一个熟悉 一般使用decodeObject:forKey方法反序列化属性 */ - (nullable instancetype)initWithCoder @synthesize accountNumber = _accountNumber; @synthesize balance = _balance; //反序列化 - (instancetype)initWithCoder :(NSCoder *)aDecoder { /*NSObject没有遵守NSCoding协议,因此调用父类的init构造方法 如果继承的父类遵守NSCoding协议需要调用父类的initWithCoder :方法 [super initWithCoder:aDecoder] */ if (self = [super init]) { self.accountNumber 关于NSCoding协议的使用是比较简单的,需要注意的就是在initWithCoder:方法中调用父类构造函数的方式。 备注 由于作者水平有限,难免出现纰漏,如有问题还请不吝赐教。