假设我们的-init方法只调用消息self,为什么通常检查self != nil消息nil是否无效?
假设我们有一个初始化器如下:
- (id)init
{
self = [super init];
if (self) {
[self doThis];
[self setFoo:@"Bar"];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
self我们可以写下:而不是检查:
- (id)init
{
self = [super init];
[self doThis];
[self setFoo:@"Bar"];
return self;
}
Run Code Online (Sandbox Code Playgroud)
现在如果由于某种原因[super init]返回nil,据我所知,该方法的结果没有区别.为什么我们会经常执行此检查?
您可以将消息发送到nil,但是您无法访问nil的实例变量.你会得到一个EXC_BAD_ACCESS例外.
考虑一个具有实例变量的类:
@implementation MyObject {
int instanceVariable;
}
- (id)init {
self = [super init];
instanceVariable = 7;
return self;
}
Run Code Online (Sandbox Code Playgroud)
如果[super init]在此示例中返回nil 会发生什么?您将尝试instanceVariable从空指针访问它,您将获得异常.
即使您没有访问任何实例变量,如果您不检查,其他事情肯定会出错self == nil.您可以轻松地泄漏malloc分配的内存或文件句柄,或者将自己传递给一些不期望为零的方法.
其他答案声称,如果您不检查零,您可以泄漏对象.例如:
@implementation MyObject
@synthesize someProperty; // assume it's an NSObject *
- (id)init {
self = [super init];
[self setSomeProperty:[[NSObject alloc] init]];
return self;
}
Run Code Online (Sandbox Code Playgroud)
这不会在ARC下泄漏,即使self是零.在手动引用计数(MRC)下,此示例将泄漏是否self为零,因为没有任何东西可以平衡+1保留计数[NSObject alloc].
在MRC下进行此操作的正确方法是:
- (id)init {
self = [super init];
[self setSomeProperty:[[[NSObject alloc] init] autorelease]];
}
Run Code Online (Sandbox Code Playgroud)
或这个:
- (id)init {
self = [super init];
NSObject *object = [[NSObject alloc] init];
[self setSomeProperty:object];
[object release];
return self;
}
Run Code Online (Sandbox Code Playgroud)
这些都不会泄漏,无论是否self为零.
如果你绕过setter方法,就像这样,如果self是nil ,你就会崩溃:
- (id)init {
self = [super init];
_someProperty = [[NSObject alloc] init];
return self;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |