NSCopying 구현
NSCopying
문서를 읽었 지만 필요한 것을 구현하는 방법에 대해 여전히 잘 모르겠습니다.
내 수업 Vendor
:
@interface Vendor : NSObject
{
NSString *vendorID;
NSMutableArray *availableCars;
BOOL atAirport;
}
@property (nonatomic, copy) NSString *vendorID;
@property (nonatomic, retain) NSMutableArray *availableCars;
@property (nonatomic, assign) BOOL atAirport;
- (id)initFromVehVendorAvailsDictionary:(NSDictionary *)vehVendorAvails;
@end
Vendor
클래스라는 객체의 배열이있다 Car
.
내 Car
물건 :
@interface Car : NSObject
{
BOOL isAvailable;
NSString *transmissionType;
NSMutableArray *vehicleCharges;
NSMutableArray *fees;
}
@property (nonatomic, assign) BOOL isAvailable;
@property (nonatomic, copy) NSString *transmissionType;
@property (nonatomic, retain) NSMutableArray *vehicleCharges;
@property (nonatomic, retain) NSMutableArray *fees;
- (id) initFromVehicleDictionary:(NSDictionary *)vehicleDictionary;
@end
그래서, 객체 Vendor
의 배열을 보유 Car
합니다. Car
다른 사용자 지정 개체의 배열 2 개를 보유합니다.
Vendor
및 둘 다 Car
사전에서 초기화됩니다. 이 방법 중 하나를 추가하겠습니다. 관련성이있을 수도 있고 아닐 수도 있습니다.
-(id)initFromVehVendorAvailsDictionary:(NSDictionary *)vehVendorAvails {
self.vendorCode = [[vehVendorAvails objectForKey:@"Vendor"]
objectForKey:@"@Code"];
self.vendorName = [[vehVendorAvails objectForKey:@"Vendor"]
objectForKey:@"@CompanyShortName"];
self.vendorDivision = [[vehVendorAvails objectForKey:@"Vendor"]
objectForKey:@"@Division"];
self.locationCode = [[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"@Code"];
self.atAirport = [[[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"@AtAirport"] boolValue];
self.venLocationName = [[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"@Name"];
self.venAddress = [[[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"Address"]
objectForKey:@"AddressLine"];
self.venCountryCode = [[[[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"Address"]
objectForKey:@"CountryName"]
objectForKey:@"@Code"];
self.venPhone = [[[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"LocationDetails"]
objectForKey:@"Telephone"]
objectForKey:@"@PhoneNumber"];
availableCars = [[NSMutableArray alloc] init];
NSMutableArray *cars = (NSMutableArray *)[vehVendorAvails objectForKey:@"VehAvails"];
for (int i = 0; i < [cars count]; i++) {
Car *car = [[Car alloc] initFromVehicleDictionary:[cars objectAtIndex:i]];
[availableCars addObject:car];
[car release];
}
self.venLogo = [[[vehVendorAvails objectForKey:@"Info"]
objectForKey:@"TPA_Extensions"]
objectForKey:@"VendorPictureURL"];
return self;
}
그래서 무서운 문제를 요약합니다.
Vendor
객체 배열을 복사해야 합니다. 에서 NSCopying
프로토콜 을 구현해야한다고 생각 Vendor
하는데, s 배열을 보유하고 Car
있기 때문에 구현해야 할 수도 있습니다 . 즉, 객체에 속한 2 개의 배열에있는 클래스에서도이를 구현해야 합니다.Vendor
Car
Car
에서 NSCopying
프로토콜을 구현하는 방법에 대한 지침을 얻을 수 있다면 정말 감사하겠습니다. 여기에 Vendor
대한 튜토리얼은 어디에서도 찾을 수 없습니다.
NSCopying 을 구현하려면 객체가 -copyWithZone:
선택자에 응답해야합니다 . 준수를 선언하는 방법은 다음과 같습니다.
@interface MyObject : NSObject <NSCopying> {
그런 다음 개체의 구현 ( .m
파일)에서 :
- (id)copyWithZone:(NSZone *)zone
{
// Copying code here.
}
코드는 무엇을해야합니까? 먼저 객체의 새 인스턴스를 만듭니다. 호출 [[[self class] alloc] init]
하여 현재 클래스의 초기화 된 객체를 가져올 수 있습니다.이 객체는 서브 클래 싱에 적합합니다. 그런 다음 NSObject
복사를 지원 하는의 하위 클래스 인 인스턴스 변수 [thatObject copyWithZone:zone]
에 대해 새 개체를 호출 할 수 있습니다 . 기본 유형 (int
, char
, BOOL
and friends) just set the variables to be equal. So, for your obejct Vendor, it’d look like this:
- (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;
}
This answer is similar to the accepted, but uses allocWithZone:
and is updated for ARC. NSZone is foundation class for allocating memory. While ignoring NSZone
might work for most cases, it is still incorrect.
To correctly implement NSCopying
you must implement a protocol method which allocates a new copy of the object, with properties that match the values of the original.
헤더의 인터페이스 선언에서 클래스가 NSCopying
프로토콜을 구현하도록 지정 합니다.
@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;
}
스위프트 버전
그냥 전화 해 object.copy()
to create the copy.
copy()
값 유형은 "자동으로"복사되므로 사용하지 않았습니다 . 하지만 나는 사용해야했다copy()
for class
types.
docsNSZone
때문에 매개 변수를 무시했습니다. say it is deprecated:
이 매개 변수는 무시됩니다. Objective-C는 메모리 영역을 더 이상 사용하지 않습니다.
Also, please note that this is a simplified implementation. If you have subclasses it gets a bit tricker and you should use dynamic type: 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
}
}
참고URL : https://stackoverflow.com/questions/4089238/implementing-nscopying
'development' 카테고리의 다른 글
Common Lisp의 LET 대 LET * (0) | 2020.10.09 |
---|---|
PHP file_get_contents ()가 "스트림 열기 실패 : HTTP 요청 실패!"를 반환합니다. (0) | 2020.10.09 |
replaceState () 대 pushState () (0) | 2020.10.09 |
C에서이 논리 AND 버전이 단락 동작을 표시하지 않는 이유는 무엇입니까? (0) | 2020.10.09 |
ZonedDateTime을 날짜로 변환하는 방법? (0) | 2020.10.09 |