Objective-C如何自己实现一个基于数组下标的属性访问模式

在iOS6.0以及OS X10.8之后,Apple引入了一套非正式协议(informal protocol)与Objective-C语法直接绑定。当你实现了这其中的方法之后即可使用数组下标来访问属性元素

在Foundation库中,NSArray类实现了- (id)objectAtIndexedSubscript:(NSUInteger)idx方法。因此,我们可以这么来访问数组元素:

NSArray *arr = @[@100, @200, @300];

NSNumber *num = arr[0];

上述arr[0]就相当于[arr objectAtIndex:0]。

而NSMutableArray在基于NSArray的基础上又实现了- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index方法。这样我们可以通过数组下标来读写相应元素,比如:

NSMutableArray *arr = [NSMutableArray arrayWithArray:@[@100, @200, @300]];

arr[2] = arr[0];

而NSDictionary类实现了- (id)objectForKeyedSubscript:(id)key方法。这样我们能以数组下标的形式来访问相应键的值。比如:

NSDictionary *dict = @{@"key" : @"value"};

NSString *value = dict[@"key"];

而NSMutableDictionary在NSDictionary类的基础上又实现了- (void)setObject:(id)object forKeyedSubscript:(id < NSCopying >)aKey方法。这样,我们能以数组下标的方式来读写相应键的值。比如:

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{@"key":"@Hello"}];

dict[dict[@"key"]] = @"world";

下面我们通过实现这四个方法,自己实现一个能同时使用这四种下标方式访问模式的类。


//

//  main.m

//  objCTest

//

//  Created by Zenny Chen on 12-2-7.

//  Copyright (c) 2014年 Neon Media Studio. All rights reserved.

//

#import <Foundation/Foundation.h>

@interface MyContainer : NSObject

{

@private

NSMutableDictionary *mDict;

NSMutableArray *mArray;

}

- (void)setObject:(id)object forKeyedSubscript:(id < NSCopying >)aKey;

- (id)objectForKeyedSubscript:(id)key;

- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index;

- (id)objectAtIndexedSubscript:(NSUInteger)idx;

@end

@implementation MyContainer

- (instancetype)init

{

self = [super init];

mDict = [[NSMutableDictionary alloc] initWithDictionary:@{@"key1":@"value1", @"key2":@"value2"}];

mArray = [[NSMutableArray alloc] initWithArray:@[@100, @200, @300, @400]];

return self;

}

- (void)dealloc

{

if(mDict != nil)

{

[mDict removeAllObjects];

[mDict release];

mDict = nil;

}

if(mArray != nil)

{

[mArray removeAllObjects];

[mArray release];

mArray = nil;

}

[super dealloc];

}

- (void)setObject:(id)object forKeyedSubscript:(id < NSCopying >)aKey

{

[mDict setObject:object forKey:aKey];

}

- (id)objectForKeyedSubscript:(id)key

{

return [mDict objectForKey:key];

}

- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index

{

const NSUInteger length = [mArray count];

if(index > length)

return;

if(index == length)

[mArray addObject:anObject];

else

[mArray replaceObjectAtIndex:index withObject:anObject];

}

- (id)objectAtIndexedSubscript:(NSUInteger)idx

{

if(idx >= [mArray count])

return nil;

return [mArray objectAtIndex:idx];

}

@end

int main (int argc, const char * argv[])

{

@autoreleasepool

{

// insert code here...

MyContainer *cont = [[MyContainer alloc] init];

cont[@"mykey"] = @"myvalye";

NSLog(@"key1 is: %@", cont[@"key1"]);

NSLog(@"key2 is: %@", cont[@"key2"]);

NSLog(@"mykey is: %@", cont[@"mykey"]);

cont[4] = @500;

cont[2] = @-300;

NSLog(@"The value[4] = %@", cont[4]);

NSLog(@"The value[3] = %@", cont[3]);

NSLog(@"The value[2] = %@", cont[2]);

}

return 0;

}

时间: 2024-11-19 08:31:14

Objective-C如何自己实现一个基于数组下标的属性访问模式的相关文章

教你如何使用Java手写一个基于数组实现的队列

一.概述 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表.在具体应用中通常用链表或者数组来实现.队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作.队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加. 在Java中队列又可以分为两个大类,一种是阻塞队列和非阻塞队列. 1.没有实现阻塞接口: 1)实现java.util.Queue的LinkList, 2)实现java.util.Abstra

开源一个基于nio的java网络程序

因为最近要从公司离职,害怕用nio写的网络程序没有人能看懂(或许是因为写的不好吧),就调整成了mina(这样大家接触起来非常方便,即使没有socket基础,用起来也不难),所以之前基于nio写的网络程序就开放出来好了! 写的比较挫,大家见谅! 首先是PollServer类,主要处理select,做网络事件的监听和基于FutureTask的数据发送,代码如下: package gs.gate; import gs.gate.handle.ClientHandle; import java.util

基于数组实现的单链表(兼具Boost单元测试)

对于单链表,我们大多时候会用指针来实现(可参考基于指针实现的单链表).现在我们就来看看怎么用数组来实现单链表. 1. 定义单链表中结点的数据结构 1 typedef int ElementType; 2 class NodeType 3 { 4 public: 5 ElementType data; 6 int next; 7 }; 该结点包括了两个元素,其一是数据,另一个是指向下一个结点的"指针"(在这篇文章中实际上是指用于实现单链表的数组的下标.)  2. 定义一个的数组 1 co

基于数组实现Java 自定义Queue队列及应用

Java 自定义队列Queue: 队列的抽象数据类型就是一个容器,其中的对象排成一个序列,我们只能访问和取出排在最前端( Front)的对象,只能在队列的尾部( Rear)插入新对象.正是按照这一规则,才能保证最先被插入的对象首先被删除( FIFO).java本身是有自带Queue类包,为了达到学习目的已经更好深入了解Queue队列,自己动手自建java Queue类是个很好的学习开始: 基于数组的实现 ? 顺序数组 借助一个定长数组 Q 来存放对象,即可简单地实现队列.那么,为了符合 FIFO

Java 基于数组自定义实现容量不可变向量Vector

背景:假定集合 S 由 n 个元素组成,它们按照线性次序存放,于是我们就可以直接访问其中的第一个元素.第二个元素.第三个元素--.也就是说,通过[0, n-1]之间的每一个整数,都可以直接访问到唯一的元素 e,而这个整数就等于 S 中位于 e 之前的元素个数??在此,我们称之为该元素的秩( Rank).不难看出,若元素 e 的秩为 r,则只要 e 的直接前驱(或直接后继)存在,其秩就是 r-1(或 r+1).这一定义与 Java. C++之类的程序语言中关于数组元素的编号规则是一致的.支持通过秩

基于数组二分查找算法的实现

基于数组二分查找算法的实现 二分查找 查找 算法 赵振江 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功

扩展一个boot的插件—tooltip&amp;做一个基于boot的表达验证

在线演示 本地下载 (代码太多请查看原文) 加班,加班加班,我爱加班··· 我已经疯了,哦也. 这次发一个刚接触boot的时候用boot做的表单验证,我们扩展一下tooltip的插件,让他可以换颜色. 其实挺简单的,主要是考究代码阅读的能力. boot的代码写的很简单,能省略“;”的地方就省略掉了,而且他的闭包也很有意思 +function($){ }(jQuery); 这种写法等同于 (function($){ })(jQuery); 少些一个符号,比较节俭. 他的对外接口写的就比较正常了:

笔记六:基于数组的栈的实现

栈 定义:后进先出的数据结构 实现一:基于数组表示的线性表的派生栈的实现. 原理:把线性表的插入和删除操作限制在同一端进行,即得到栈的表现形式. 操作:把数组线性表的右端定义为栈顶. 代码: template<typename T> class stack { public: virtual ~stack() {}; virtual bool empty() const = 0; virtual int size() const = 0; virtual T& top() = 0; v

数据结构 - 基于数组的队列

队列Queue *队列也是一种线性结构 *相比于数组,队列对应的操作是数组的子集 *只能从一端(队尾)添加元素,从另一端(队首)取出元素 *队列是一种先进先出的数据结构(先到先得 First In First Out) 基于数组的队列实现的源码如下: package queue; public interface Queue<E> {        public void enqueue(E e);        public E dequeue();        public E getF