3 回答

TA貢獻1860條經驗 獲得超8個贊
要實現NSCopying,您的對象必須響應-copyWithZone:選擇器。聲明符合條件的方式如下:
@interface MyObject : NSObject <NSCopying> {
然后,在對象的實現中(您的.m文件):
- (id)copyWithZone:(NSZone *)zone
{
// Copying code here.
}
您的代碼應該做什么?首先,創(chuàng)建該對象的新實例-您可以調用[[[self class] alloc] init]以獲取當前類的初始化對象,該對象對子類非常有用。然后,對于NSObject支持復制的子類的任何實例變量,可以調用[thatObject copyWithZone:zone]新對象。對于原始類型(int,char,BOOL和朋友)剛剛成立的變量是相等的。因此,對于您的目標供應商,它看起來像這樣:
- (id)copyWithZone:(NSZone *)zone
{
id copy = [[[self class] alloc] init];
if (copy) {
// Copy NSObject subclasses
[copy setVendorID:[[self.vendorID copyWithZone:zone] autorelease]];
[copy setAvailableCars:[[self.availableCars copyWithZone:zone] autorelease]];
// Set primitives
[copy setAtAirport:self.atAirport];
}
return copy;
}

TA貢獻1815條經驗 獲得超10個贊
該答案與已接受的答案相似,但是使用allocWithZone:并針對ARC更新了該答案。NSZone是分配內存的基礎類。盡管NSZone在大多數情況下忽略可能有效,但這仍然是不正確的。
為了正確實現,NSCopying您必須實現一種協(xié)議方法,該方法分配具有與原始值匹配的屬性的對象的新副本。
在標題的接口聲明中,指定您的類實現了該NSCopying協(xié)議:
@interface Car : NSObject<NSCopying>
{
...
}
在.m實現中,添加一個-(id)copyWithZone類似于以下內容的方法:
- (id)copyWithZone:(NSZone*)zone
{
Car* carCopy = [[[self class] allocWithZone:zone] init];
if (carCopy)
{
carCopy.isAvailable = _isAvailable;
carCopy.transmissionType = _transmissionType;
... // assign all other properties.
}
return carCopy;
}

TA貢獻1946條經驗 獲得超4個贊
只需調用object.copy()即可創(chuàng)建副本。
我沒有使用copy()過值類型,因為它們是“自動”復制的。但是,我不得不使用copy()的class類型。
我忽略了該NSZone參數,因為文檔稱它已棄用:
該參數被忽略。存儲區(qū)不再由Objective-C使用。
另外,請注意,這是一個簡化的實現。如果您有子類,它會變得有些棘手,您應該使用動態(tài)類型:type(of: self).init(transmissionType: transmissionType)。
class Vendor {
let vendorId: String
var availableCars: [Car] = []
init(vendorId: String) {
self.vendorId = vendorId
}
}
extension Vendor: NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
let copy = Vendor(vendorId: vendorId)
if let availableCarsCopy = availableCars.map({$0.copy()}) as? [Car] {
copy.availableCars = availableCarsCopy
}
return copy
}
}
class Car {
let transmissionType: String
var isAvailable: Bool = false
var fees: [Double] = []
init(transmissionType: String) {
self.transmissionType = transmissionType
}
}
extension Car: NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
let copy = Car(transmissionType: transmissionType)
copy.isAvailable = isAvailable
copy.fees = fees
return copy
}
}
- 3 回答
- 0 關注
- 740 瀏覽
添加回答
舉報