Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Objective-C.Programming.pdf
Скачиваний:
14
Добавлен:
21.02.2016
Размер:
8.64 Mб
Скачать

Chapter 30 Properties

However, you used the @synthesize construct to implement them:

@synthesize productName, voltage;

Objective-C compiler trivia: When compiling for iOS or a 64-bit Mac OS X program, you don’t need to declare the instance variables. The @property/@synthesize calls are sufficient to make the space for the data.

Open up Appliances and comment out the instance variables in Appliance.h:

{

//NSString *productName;

//int voltage;

}

Rebuild and run the program.

In this book, we always declare the instance variables. It is a nice form of documentation and makes your code usable within 32-bit Mac OS X programs. Uncomment the instance variables.

Property attributes

Now let’s take a closer look at the different attributes you can use to control how the accessors for a property will be created.

Mutability

A property can be declared readwrite or readonly. The default is readwrite, which means that both a setter and a getter method are created. If you don’t want a setter method to be created, you mark the property as readonly:

@property (readonly) int voltage;

Lifetime specifiers

A property can also be declared unsafe_unretained, strong, weak, or copy. This option determines how the setter handles its memory management.

unsafe_unretained is the default and the simplest: it just assigns the passed-in value to the property. Imagine this declaration and definition:

@property (unsafe_unretained) int averageScore;

// "@property int averageScore" would also work here

...

@synthesize averageScore;

This would result in a setter method that’s pretty much equivalent to:

- (void)setAverageScore:(int)d

{

averageScore = d;

}

In Appliance, voltage is an unsafe, unretained property. You will always use unsafe_unretained for properties that hold non-objects.

218

Lifetime specifiers

strong, as you learned in Chapter 20, will ensure that a strong reference is kept to the passed-in object. It will also let go of ownership of the old object (which will then deallocate itself if it has no other owners). For properties that hold objects, you will usually use strong.

weak does not imply ownership of the object pointed to. It will synthesize a setter that sets the property to the passed-in object. If this object is deallocated, the property will be set to nil. (Note that if the pointer is unsafe_unretained and the object it points to is deallocated, you will have a “dangling pointer.” Sending a message to a dangling pointer usually crashes your program.)

copy forms a strong reference to a copy of the object passed in. But, there is a detail in this that most

people misunderstand...

copy

The copy option makes a copy of an object and then changes the pointer to refer to this copy. Imagine you had a property declaration and definition like this:

@property (copy) NSString *lastName; @synthesize lastName;

The generated setter method would look somewhat like this:

- (void)setLastName:(NSString *)d

{

lastName = [d copy];

}

Use of the copy attribute is most common with object types that have mutable subclasses. For example, NSString has a subclass called NSMutableString. You can imagine that your setLastName: method might be passed a mutable string:

// Create a mutable string

NSMutableString *x = [[NSMutableString alloc] initWithString:@"Ono"];

//Pass it to setLastName: [myObj setLastName:x];

//'copy' prevents this from changing the lastName [x appendString:@" Lennon"];

What if the object passed in is not mutable? It seems wasteful to make a copy of an immutable object. The copy method just calls copyWithZone: and passes nil as the argument. For example, in NSString, the copyWithZone: method is overridden to look like this:

- (id)copyWithZone:(NSZone *)z

{

return self;

}

That is, it doesn’t make a copy at all. (Note that NSZone and memory zoning in general are all but deprecated, vestigial features of Cocoa programming, so we won’t go further into them here. copyWithZone: still has some use, however, and has not been entirely phased out.)

For objects that come in mutable and immutable versions, the copy method returns an immutable copy. For example, NSMutableString has a copy method that returns an instance of NSString. If you want the copy to be a mutable object, use the mutableCopy method.

219

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]