In Objective-C it takes two steps to create an object;in order,you must
. Allocate memory to store the new object.
. Initialize the newly allocated memory to appropriate values.
An object isn't fully functional until both steps are completed.
1、Creating and initializing objects
For objects that inherit from NSObject,memory for new objects is typically allocated by calling
the class method alloc.例如:CTRentalProperty *newRental = [CTRentalProperty alloc];
This statement uses the alloc method to reserve enough memory to store all the instance variables associated with a CTRentalProperty object.
You don't need to write your own implementation of the alloc method because the default version
inherited from NSObject is suitable.
Most objects,however,do require additional initialization once the memory has been allocated.
By convention,this initialization is achieved by calling a method named init:
CTRentalProperty *newRental = [CTRentalProperty alloc];
[newRental init];
It's even possible to perform both of these steps in a single line by nesting the message
sends as follows:
CTRentalProperty *newRental = [[CTRentalProperty alloc] init];
What do uninitialized instance variables get set to?
Unlike typical C-style memory allocation strategies,the memory returned by alloc has each
instance variable initialized to the value zero(or its equivalent:nil,NULL,NO,0.0,and so on).
这就意味着,你不必多此一举地将变量初始化为这样的值。
isConfigured may be a better instance variable name than needsConfiguration.
The code snippet that called alloc and init on separate lines has a silent but potentially
fatal flaw.Alough it may not be a problem with most classes,it's possible for init to return
an object different from the one created by alloc.
In coding terms this means you should always store the return value of init;here is a bad
example:
CTRentalProperty *newRental = [CTRentalProperty alloc];
[newRental init];
And here is a good example:
CTRentalProperty *newRental = [CTRentalProperty alloc];
newRental = [newRental init];
所以,干脆这么写CTRentalProperty *newRental = [[CTRentalProperty alloc] init];就没事了。
你可能会好奇什么情况下init可能会返回一个不同于alloc分配的那个对象。对于大多数类,这种情况
从不会发生,但是在特殊的情况下(implementing singletons,caches,or named instances,
and so on),a class developer may decide to more tightly control when objects are created,
preferring to return an existing object that's equivalent rather than initialize a new one,
for example.
It isn't always possible for an initialization method to perform its intended task.In such
cases it's common for the init method to free the memory associated with the new object and
return nil,indicating that the requested object couldn't be initialized.
If there's a chance that your initialization method may fail,you may like to explicitly
check for this condition,as demonstrated here:
CTRentalProperty newRental = [[CTRentalProperty alloc] init];
if (newRental == nil) {
NSLog(@"Failed to create new rental property");
}
An initialization method that accepts no parameters has limited practical use.Typically,
a class provides one or more specialized initialization methods.These methods are commonly
named using the form initWithXYZ:,where XYZ is replaced with a description of any additional
parameters required to properly initialize the object.
例如,将下面的方法声明添加到CTRentalProperty类的@interface部分:
- (id)initWithAddress:(NSString *)newAddress
rentalPrice:(float)newRentalPrice
andType:(PropertyType)newPropertyType;
下面是CTRentalProperty类的@implementation部分对此方法声明的实现:
- (id)initWithAddress:(NSString *)newAddress
rentalPrice:(float)newRentalPrice
andType:(PropertyType)newPropertyType
{
if ((self = [super init])) {
self.address = newAddress;
self.rentalPrice = newRentalPrice;
self.propertyType = newPropertyType;
}
return self;
}
上面的代码有些地方要解释一下:Working from right to left,it first sends the init message to
super.super is a keyword,similar to self,that enables you to send messages to the superclass.
Before you initialize any of your own instance variables,it's important to provide your
superclass a chance to initialize its own state.The object returned by the superclass's init
method is then assigned to self in case it has substituted your object for another.You then
check this value to ensure it isn't nil,
如果,你喜欢的话,也可以写成2行:
self = [super init];
if (self != nil) {
}
Because it's common to allocate an object and then want to immediately initialize it,many
classes provide convenience methods that combine the two steps into one.These class methods
are typically named after the class that contains them.A good example is NSString's
stringWithFormat: method,which allocates and initializes a new string with the contents
generated by the specified format string.
To allow users to easily create a new rental property object, add the following class
method to the CTRentalProperty class:
+ (id)rentalPropertyOfType:(PropertyType)newPropertyType
rentingFor:(float)newRentalPrice
atAddress:(NSString *)newAddress;
Being a class method,rentalPropertyOfType:rentingFor:atAddress: allows you to invoke the
method without first creating an object.下面是此方法的实现:
+ (id)rentalPropertyOfType:(PropertyType)newPropertyType
rentingFor:(float)newRentalPrice
atAddress:(NSString *)newAddress
{
id newObject = [[CTRentalProperty alloc]
initWithAddress:newAddress
rentalPrice:newRentalPrice
andType:newPropertyType];
return [newObject autorelease];
}
注意,上面的代码用了本来就有的alloc和前面早就有的initWithAddress:rentingFor:andType: 方法。
还有就是还发送了一个autorelase消息,这和内存有关。
接下来就是谈谈如何销毁对象。If you don’t destroy these objects, they’ll eventually consume enough memory that the iPhone will think your application is the next Chernobyl and shut it
down to avoid impacting other phone functionality!
If you forget this step, the memory will forever hold your object even if you never use it again. In Objective-C (at least when targeting the iPhone), it’s your responsibility to manage memory usage explicitly.
Unlike languages such as C# and Java, Objective-C has no automated detection and reclaiming of unwanted objects, a feature commonly known as garbage collection.
CTRentalProperty *newRental = [[CTRentalProperty alloc]
initWithAddress:@"13 Adamson Crescent"
rentingFor:275.0f
andType:TownHouse];
... make use of the object ...
[newRental release];
newRental = nil;
尽管你应当调用release来指明你对此对象已经不感兴趣了,但这并不会确保立刻就把此对象销毁掉。
你的应用的其他部分可能还想此对象存活,只有当最后的一个引用被释放后,该对象才会被释放。
当release最后判断出没人还要此对象活着时,它就会自动调用另一个方法,叫dealloc,来清理掉
此对象。
如何实现CTRentalProperty的dealloc方法:
- (void)dealloc {
[address release];
[super dealloc];
}
在dealloc中也适合清理掉任何系统资源(如文件、网络sockets,或数据库handles)。
还有要注意,尽管declared properties可以自动提供getter和setter实现,但它们并没有在dealloc中
生成代码来释放它们关联的内存。如果你的类里有一些属性使用了retain或copy语义,你必须手动
在dealloc中编写清除它们所使用的内存的代码。上面代码中[address release]就是此用法。
Finally,most dealloc method implementations end with a call to [super dealloc].This gives
the superclass a chance to free any resources it has allocated.Notice that the order here
is important.
Creating and destroying objects
最新推荐文章于 2020-03-22 12:08:15 发布