NSDictnary 等对象的继承实现

转载 2012年03月30日 10:02:56

/*
 CHDataStructures.framework -- CHMultiDictionary.h
 
 Copyright (c) 2008-2010, Quinn Taylor <http://homepage.mac.com/quinntaylor>
 
 This source code is released under the ISC License. <http://www.opensource.org/licenses/isc-license>
 
 Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
 
 The software is  provided "as is", without warranty of any kind, including all implied warranties of merchantability and fitness. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
 */

#import "CHMutableDictionary.h"

/**
 @file CHMultiDictionary.h
 
 A <a href="http://en.wikipedia.org/wiki/Multimap_(data_structure)">multimap</a> in which multiple values may be associated with a given key.
 */

/**
 A <a href="http://en.wikipedia.org/wiki/Multimap_(data_structure)">multimap</a> implementation, in which multiple values may be associated with a given key.
 
 A map is the same as a "dictionary", "associative array", etc. and consists of a unique set of keys and a collection of values. In a standard map, each key is associated with one value; in a multimap, more than one value may be associated with a given key. A multimap is appropriate for any situation in which one item may correspond to (map to) multiple values, such as a term in an book index and occurrences of that term, courses for which a student is registered, etc.
 
 The values for a key may or may not be ordered. This implementation does not maintain an ordering for objects associated with a key, nor does it allow for multiple occurrences of an object associated with the same key. Internally, this class uses an NSMutableDictionary, and the associated values for each key are stored in distinct NSMutableSet instances. (Just as with NSDictionary, each key added to a CHMultiDictionary is copied using \link NSCopying#copyWithZone: -copyWithZone:\endlink and all keys must conform to the NSCopying protocol.) Objects are retained on insertion and released on removal or deallocation.
 
 Since NSDictionary and NSSet conform to the NSCoding protocol, any internal data can be serialized. However, NSSet cannot automatically be written to or read from a property list, since it has no specified order. Thus, instances of CHMultiDictionary must be encoded as an NSData object before saving to disk.
 
 Currently, this implementation does not support key-value coding, observing, or binding like NSDictionary does. Consequently, the distinction between "object" and "value" is blurrier, although hopefully consistent with the Cocoa APIs in general....
 
 Unlike NSDictionary and other Cocoa collections, CHMultiDictionary has not been designed with mutable and immutable variants. A multimap is not that much more useful if it is immutable, so any copies made of this class are mutable by definition.
 */
@interface CHMultiDictionary : CHMutableDictionary {
	NSUInteger objectCount; // Number of objects currently in the dictionary.
}

#pragma mark Querying Contents

/**
 Returns the number of objects in the receiver, associated with any key.
 
 @return The number of objects in the receiver. This is the sum total of objects associated with each key in the dictonary.
 
 @see allObjects
 */
- (NSUInteger) countForAllKeys;

/**
 Returns the number of objects associated with a given key.
 
 @param aKey The key for which to return the object count.
 @return The number of objects associated with a given key in the dictionary.
 
 @see objectsForKey:
 */
- (NSUInteger) countForKey:(id)aKey;

/**
 Returns an array of objects associated with a given key.
 
 @param aKey The key for which to return the corresponding objects.
 @return An NSSet of objects associated with a given key, or nil if the key is not in the receiver.
 
 @see countForKey:
 @see removeObjectsForKey:
 */
- (NSSet*) objectsForKey:(id)aKey;

#pragma mark Modifying Contents

/**
 Adds a given object to an entry for a given key in the receiver.
 
 @param aKey The key with which to associate @a anObject.
 @param anObject An object to add to an entry for @a aKey in the receiver. If an entry for @a aKey already exists in the receiver, @a anObject is added using \link NSMutableSet#addObject: -[NSMutableSet addObject:]\endlink, otherwise a new entry is created.
 
 @throw NSInvalidArgumentException if @a aKey or @a anObject is @c nil.
 
 @see addObjects:forKey:
 @see objectsForKey:
 @see removeObjectsForKey:
 @see setObjects:forKey:
 */
- (void) addObject:(id)anObject forKey:(id)aKey;

/**
 Adds the given object(s) to a key entry in the receiver.
 
 @param aKey The key with which to associate @a anObject.
 @param objectSet A set of objects to add to an entry for @a aKey in the receiver. If an entry for @a aKey already exists in the receiver, @a anObject is added using \link NSMutableSet#unionSet: -[NSMutableSet unionSet:]\endlink, otherwise a new entry is created.
 
 @throw NSInvalidArgumentException if @a aKey or @a objectSet is @c nil.
 
 @see addObject:forKey:
 @see objectsForKey:
 @see removeObjectsForKey:
 @see setObjects:forKey:
 */
- (void) addObjects:(NSSet*)objectSet forKey:(id)aKey;

/**
 Remove @b all occurrences of @a anObject associated with a given key.
 
 @param aKey The key for which to remove an entry.
 @param anObject An object (possibly) associated with @a aKey in the receiver. Objects are considered to be equal if -compare: returns NSOrderedSame.
 
 @throw NSInvalidArgumentException if @a aKey or @a anObject is @c nil.
 
 If @a aKey does not exist in the receiver, or if @a anObject is not associated with @a aKey, the contents of the receiver are not modified.
 
 @see containsObject
 @see objectsForKey:
 @see removeObjectsForKey:
 */
- (void) removeObject:(id)anObject forKey:(id)aKey;

/**
 Remove a given key and its associated value(s) from the receiver.
 
 @param aKey The key for which to remove an entry.
 
 If @a aKey does not exist in the receiver, there is no effect on the receiver.
 
 @see objectsForKey:
 @see removeObject:forKey:
 */
- (void) removeObjectsForKey:(id)aKey;

/**
 Sets the object(s) associated with a key entry in the receiver.
 
 @param aKey The key with which to associate the objects in @a objectSet.
 @param objectSet A set of objects to associate with @a key. If @a objectSet is empty, the contents of the receiver are not modified. If an entry for @a key already exists in the receiver, @a objectSet is added using \link NSMutableSet#setSet: -[NSMutableSet setSet:]\endlink, otherwise a new entry is created.
 
 @throw NSInvalidArgumentException if @a aKey or @a objectSet is @c nil.
 
 @see addObject:forKey:
 @see addObjects:forKey:
 @see objectsForKey:
 @see removeObjectsForKey:
 */
- (void) setObjects:(NSSet*)objectSet forKey:(id)aKey;

@end


/*
 CHDataStructures.framework -- CHMultiDictionary.m
 
 Copyright (c) 2008-2010, Quinn Taylor <http://homepage.mac.com/quinntaylor>
 
 This source code is released under the ISC License. <http://www.opensource.org/licenses/isc-license>
 
 Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
 
 The software is  provided "as is", without warranty of any kind, including all implied warranties of merchantability and fitness. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
 */

#import "CHMultiDictionary.h"

/**
 Utility function for creating a new NSMutableSet containing object; if object is a set or array, the set containts all objects in the collection.
 */
static inline NSMutableSet* createMutableSetFromObject(id object) {
	if (object == nil)
		return nil;
	if ([object isKindOfClass:[NSSet class]])
		return [NSMutableSet setWithSet:object];
	if ([object isKindOfClass:[NSArray class]])
		return [NSMutableSet setWithArray:object];
	else
		return [NSMutableSet setWithObject:object];
}

#pragma mark -

@implementation CHMultiDictionary

- (id) initWithObjects:(NSArray*)objectsArray forKeys:(NSArray*)keyArray {
	if ([keyArray count] != [objectsArray count])
		CHInvalidArgumentException([self class], _cmd, @"Unequal array counts.");
	if (self = [super initWithCapacity:[objectsArray count]]) {
		NSEnumerator *objects = [objectsArray objectEnumerator];
		for (id key in keyArray) {
			[self setObject:[objects nextObject] forKey:key];
		}
	}
	return self;
}

#pragma mark Querying Contents

- (NSUInteger) countForAllKeys {
	return objectCount;
}

- (NSUInteger) countForKey:(id)aKey {
	return [[self objectForKey:aKey] count];
}

- (NSSet*) objectsForKey:(id)aKey {
	return [[[(id)dictionary objectForKey:aKey] copy] autorelease];
}

#pragma mark Modifying Contents

- (void) addObject:(id)anObject forKey:(id)aKey {
	NSMutableSet *objects = [self objectForKey:aKey];
	if (objects == nil)
		[super setObject:(objects = [NSMutableSet set]) forKey:aKey];
	else
		objectCount -= [objects count];
	[objects addObject:anObject];
	objectCount += [objects count];
}

- (void) addObjects:(NSSet*)objectSet forKey:(id)aKey {
	NSMutableSet *objects = [self objectForKey:aKey];
	if (objects == nil)
		[super setObject:(objects = [NSMutableSet set]) forKey:aKey];
	else
		objectCount -= [objects count];
	[objects unionSet:objectSet];
	objectCount += [objects count];
}

- (void) removeAllObjects {
	[super removeAllObjects];
	objectCount = 0;
}

- (void) removeObject:(id)anObject forKey:(id)aKey {
	NSMutableSet *objects = [self objectForKey:aKey];
	if ([objects containsObject:anObject]) {
		[objects removeObject:anObject];
		--objectCount;
		if ([objects count] == 0)
			[self removeObjectForKey:aKey];
	}
}

- (void) removeObjectsForKey:(id)aKey {
	objectCount -= [[self objectForKey:aKey] count];
	[self removeObjectForKey:aKey];
}

- (void) setObject:(id)anObject forKey:(id)aKey {
	NSSet *objectSet = createMutableSetFromObject(anObject);
	if (aKey != nil)
		objectCount += ([objectSet count] - [[self objectForKey:aKey] count]);
	[super setObject:objectSet forKey:aKey];
}

- (void) setObjects:(NSSet*)objectSet forKey:(id)aKey {
	[self setObject:objectSet forKey:aKey];
}

@end



像 NSArray 这样的类,直接继承,使用的时候会碰到运行期的问题。网上搜了下,这里可以实现比较好的继承


https://github.com/davedelong/CHDataStructures/downloads



面向对象与Java实现(封装、继承

  • 2012年05月14日 13:10
  • 479KB
  • 下载

26_面向对象的继承反映

  • 2016年03月28日 15:39
  • 2.12MB
  • 下载

Mybatis表对象继承实现

Mybatis表对象继承        我们一般用表来表现对象之间的继承关系时通常有三种方式。第一种是把所有对象包含的属性都存放在一张表中,然后用一个字段来区分当前记录对应的对象类型;第二种是每个子...
  • elim168
  • elim168
  • 2017年04月27日 10:49
  • 9167

php面向对象-继承

  • 2015年02月02日 10:49
  • 1.56MB
  • 下载

对象的继承关系在数据库中的实现方式和PowerDesigner设计

在面向对象的编程中,使用对象的继承是一个非常普遍的做法,但是在关系数据库管理系统RDBMS中,使用的是外键表示实体(表)之间的关系,那么对于继承关系,该怎么在RDBMS中表示呢?一般来说有3种实现方式...
  • jjting
  • jjting
  • 2012年10月12日 21:50
  • 1335

面向对象抽象思维与java继承机制

  • 2014年01月26日 17:20
  • 133KB
  • 下载

一个例子教你了解面向对象继承

  • 2014年08月15日 11:45
  • 18KB
  • 下载

混合对象 "类" ---js实现继承的两种方式

类理论类:数据和操作数据的行为的互联 js中没有类,类是它的一种设计模式。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NSDictnary 等对象的继承实现
举报原因:
原因补充:

(最多只允许输入30个字)