超テキトーに弄ってみる

あれをアレな感じであれした場合
あれってのは、ほら、Automatic Reference Counting [ARC]?

#import <Foundation/Foundation.h>

#define kCapacity 1024
@interface ObjectStack : NSObject
{
    id stack[kCapacity];
    NSInteger head, foot;
    BOOL isEmpty;
}
- (void)push:(id)object;
- (id)pop;
@end

まずあれだ。

id *stack;

ARCがこれを許さない。で、静的に決定される配列でごまかす。これはOK。

実装はこう。

#import "ObjectStack.h"

@implementation ObjectStack

- (id)init
{
    self = [super init];
    if (self) {
        head = foot = 0;
        isEmpty = YES;
    }
    
    return self;
}

- (NSInteger)next:(NSInteger)current
{
    return ( current + 1 ) % ( kCapacity + 1 );
}

- (void)push:(id)object
{
    if( [self next:foot] == head ) {
        NSException*    exception;
        exception = [NSException exceptionWithName:@"OverFlow" reason:@"Queue is over flow" userInfo:nil];
        [exception raise];
    }
    
    // stack[foot] = [object retain];  ARC Offならこう
    stack[foot] = object;
    foot = [self next:foot];
    isEmpty = NO;
}
-(id)pop
{
    id result;
    if(isEmpty) return nil;
    
    result = stack[head];
//    stack[head] = nil;    // (A)
    head = [self next:head];
    
    if(head == foot) {
        isEmpty = YES;
    }
    // return [result autorelease]; ARC Offならこう
    return result;
}

適当なかんじのキュー。スタックのコードが手元になかったとかでは多分ない。


で、プッシュしてポップしてみると解放されない。
ARCはポップされたオブジェクトが不要になったという事に気付けなかったって事。
キューが一周するとkCapacity個のオブジェクトが無駄に取り残されるって事。


Aの行のコメントを外すと解放される。
nilの代入でARCは不要になった事に気付いたって事。



まあ、ドキュメントがどこにあるのかさえ分からないまま使ってるので、ちゃんとやるとちゃんと出来るのかもしれないw