initwithcoder和 initwithframe 区别?

本文深入解析iOS开发中loadView和viewDidLoad方法的使用与区别,包括如何在不同场景下实例化类,以及它们在界面加载过程中的作用。详细解释了loadView与viewDidLoad的执行时机,并探讨了initWithNibName与awakeFromNib等其他相关方法的应用。通过对比分析,帮助开发者更好地理解和应用这些关键方法,提高iOS应用程序的开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每个ios开发者对loadView和viewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似的initWithNibName/awakeFromNib/initWithCoder放在一起还是非常容易让人混淆的.
昨天看了下苹果官方的相关文档以及几篇相关内容的网页(一 二 三),其实这个内容以前也看过,似乎也搞清楚了,可还是忘了.好急性不如烂笔头,这次一定要好好记下来.
大前提是UIViewController有一个UIView.同时,需要厘清两个概念,创建一个类和实例化一个类.在XCode中创建一个类和实例化一个类很容易区分,但是在IB(Interface Builder)中有时候就会迷糊.其实也很好区分,孤零零地创建了一个nib文件,没有和其他可被实例化的类有直接或间接关系的时候,这个类或这些类(一个nib文件俺也可能包含多个类)是没有机会被实例化的,所以这种情况只是通过ib创建了一个类,而没有实例化.真正的实例化还需要通过在Xcode用代码来读取这个nib文件.知道这两这的区别后这些方法也就容易辨认多了
viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法.
loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它.
initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.
awakeFromNib这个方法是一个类在IB中被实例化是被调用的.看了帖子发现大家都推荐使用viewDidLoad而不要使用awakeFromNib,应为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次.实际测试中发现,当一个类的awakeFromNib被调用的时候,那么这个类的viewDidLoad就不会被调用了,这个感觉很奇怪.
initWithCoder是一个类在IB中创建但在xocdde中被实例化时被调用的.比如,通过IB创建一个controller的nib文件,然后在xocde中通过initWithNibName来实例化这个controller,那么这个controller的initWithCoder会被调用.

如果你的对象是UIViewControler的子类,那么你必须调用- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil;方法去调用NIB文件初始化自身,即使那没有使用nib文件也会调用这个函数(默认情况下init方法已经为你的做这件事情了),如果你调用这个方法,并传递的两个参数为空(nil),然后类会调用-loadView去读取一个名字和你的UIViewController名字相同的nib文件,来初始化自身。如果没有这样的nib文件,你必须调用-setView:来设置一个self.view。或者重载-loadView 方法。
### 序列化与反序列化的定义 序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。这一过程通常会把内存中的对象转化为字节流,从而能够方便地在网络间传递或是持久化到磁盘上[^1]。 反序列化则是上述过程的逆向操作,即将字节流重新构造成原始的对象实例,在程序重启后可以从文件加载之前保存的数据,或者是在网络通信中处理接收到的信息并将其还原为目标类型的对象[^2]。 ### 编程中的实现方式 在不同的编程环境中,序列化反序列化有着各自的实现方法: #### Java 中的序列化机制 Java 提供了一套内置的支持来完成对象的序列化工作。只要实现了 `Serializable` 接口就可以使某个类具备被序列化的能力。当一个对象要被发送出去或者是存入文件的时候,JVM 就会对该对象及其依赖的所有其他对象自动执行序列化进程。 ```java import java.io.*; public class Person implements Serializable { private static final long serialVersionUID = 1L; String name; int age; public Person(String n, int a){ this.name=n; this.age=a; } } ``` 为了演示具体的序列化流程,下面给出一段简单的例子用于展示如何创建、序列化以及反序列化一个 `Person` 对象: ```java // 创建对象 Person person = new Person("Alice", 30); // 文件路径 String filePath = "person.ser"; try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) { // 序列化对象至指定位置 oos.writeObject(person); } catch (IOException e) { System.out.println(e.getMessage()); } try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) { // 反序列化对象 Person deserializedPerson = (Person) ois.readObject(); System.out.printf("Name: %s Age:%d\n",deserializedPerson.name ,deserializedPerson.age ); } catch (Exception ex) { System.out.println(ex.getMessage()); } ``` #### iOS 开发环境下的 NSCoding 协议 iOS 平台上的 Cocoa Cocoa Touch 框架提供了 `NSCoding` 协议作为标准接口来进行自定义对象的编码解码。开发者只需要确保自己的模型类遵从此协议,并提供必要的编码逻辑即可利用系统自带的功能轻松达成目的[^3]。 ```objc @interface MyCustomClass : NSObject<NSCoding> @property NSString *name; @end @implementation MyCustomClass - (void)encodeWithCoder:(NSCoder *)coder{ [coder encodeObject:self.name forKey:@"name"]; } - (instancetype)initWithCoder:(NSCoder *)decoder{ self = [super init]; if(self != nil){ _name = [decoder decodeObjectForKey:@"name"]; } return self; } @end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值