Objective-Cでの独自クラスについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
山田

Objective-Cでの独自クラスについて

#1

投稿記事 by 山田 » 9年前

4月から新社会人として働きます。
会社で役に立てるようにプログラムを1から勉強しているのですが、
どうしてもわからないことが出てきてしまいこちらに投稿させて頂きました。

※会社ではプログラムを使わないのですが、出来れば覚えたいです。

・やりたいことは、独自のクラスを作る。
・独自のクラスには、UserDefaultへの読み込み用、書き込み用の関数を用意する

といったことになります。
ソースがひどいですが、なんとなくそれっぽい処理を書くことが出来ました。
しかし、NSLogを呼ぶ箇所によって正しい値を取得できないことがあります。

コード:


@interface MyObject : NSObject <NSCoding>{
    NSNumber *newCheck_;
    NSNumber *favoraite_;
}

@property(nonatomic, retain) NSNumber* newCheck_;
@property(nonatomic, retain) NSNumber* favoraite_;

-(void)readData:(NSString*)path;
-(void)writeData:(NSString*)path;

@end

-----

@implementation MyObject

@synthesize newCheck_;
@synthesize favoraite_;

- (id)init
{
    if (self = [super init]) {
        self.newCheck_ = [NSNumber numberWithInt:0];
        self.favoraite_ = [NSNumber numberWithInt:0];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    // シリアライズ時に呼び出される。
    [coder encodeObject:newCheck_ forKey:@"newCheck"];
    [coder encodeObject:favoraite_ forKey:@"favoraite"];
}

- (id)initWithCoder:(NSCoder *)coder {
    // デシリアライズ時に呼び出されるイニシャライザ
    if (self = [super init]) {
        // オブジェクトの生成ではないので、retainを忘れないように。
        newCheck_ = [[coder decodeObjectForKey:@"newCheck"] retain];
        favoraite_ = [[coder decodeObjectForKey:@"favoraite"] retain];
    }
    return self;
}

-(void)readData:(NSString*)path{
    
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    // 空なら初期化
    if( [defaults objectForKey:path] == NULL ){
        self.newCheck_ = [NSNumber numberWithInt:0];
        self.favoraite_ = [NSNumber numberWithInt:0];
    }else{
        NSData* readData = (NSData*)[defaults objectForKey:path];
        self = [NSKeyedUnarchiver unarchiveObjectWithData:readData];
    }

    // test用 
    newCheck_ = [NSNumber numberWithInt:1];
    favoraite_ = [NSNumber numberWithInt:1];
    
    NSLog( @"A %@ %@ ", newCheck_, self.favoraite_ );
    
}

-(void)writeData:(NSString*)path{

    NSData* writeData = [NSKeyedArchiver archivedDataWithRootObject:self];

    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:writeData forKey:path];
    [defaults synchronize];
    
}

@end

-----

// 実装部分
MyObject *myObj = [[MyObject alloc] init];
NSString *path = [NSString stringWithFormat:@"DATA_%03d", (int)indexPath.row];
[myObj readData:path];
NSLog( @"B %@ %@ ", newCheck_, self.favoraite_ );

A地点では1,1の値がとれるのですが、Bでは0,0になってしまいます。
調べてみるとinitで設定した値がBに反映されてしまっているみたいです。

こちら原因がお分かりになる方おりませんでしょうか。
くだらない質問失礼致します。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: Objective-Cでの独自クラスについて

#2

投稿記事 by みけCAT » 9年前

Objective-Cは詳しくないのですが、initで設定しているのは関係ないオブジェクトのデータなのではないでしょうか?
【追記】反映されないではなく、反映されてしまっているでしたね…
適当にコードを補って実行したところ、A,Bともに1 1と出力されました。

コード:

#import <Foundation/Foundation.h>
 
@interface MyObject : NSObject <NSCoding>{
    NSNumber *newCheck_;
    NSNumber *favoraite_;
}
 
@property(nonatomic, retain) NSNumber* newCheck_;
@property(nonatomic, retain) NSNumber* favoraite_;
 
-(void)readData:(NSString*)path;
-(void)writeData:(NSString*)path;
 
@end

@implementation MyObject
 
@synthesize newCheck_;
@synthesize favoraite_;
 
- (id)init
{
    if (self = [super init]) {
        self.newCheck_ = [NSNumber numberWithInt:0];
        self.favoraite_ = [NSNumber numberWithInt:0];
    }
    return self;
}
 
- (void)encodeWithCoder:(NSCoder *)coder {
    // シリアライズ時に呼び出される。
    [coder encodeObject:newCheck_ forKey:@"newCheck"];
    [coder encodeObject:favoraite_ forKey:@"favoraite"];
}
 
- (id)initWithCoder:(NSCoder *)coder {
    // デシリアライズ時に呼び出されるイニシャライザ
    if (self = [super init]) {
        // オブジェクトの生成ではないので、retainを忘れないように。
        newCheck_ = [[coder decodeObjectForKey:@"newCheck"] retain];
        favoraite_ = [[coder decodeObjectForKey:@"favoraite"] retain];
    }
    return self;
}
 
-(void)readData:(NSString*)path{
    
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
 
    // 空なら初期化
    if( [defaults objectForKey:path] == NULL ){
        self.newCheck_ = [NSNumber numberWithInt:0];
        self.favoraite_ = [NSNumber numberWithInt:0];
    }else{
        NSData* readData = (NSData*)[defaults objectForKey:path];
        self = [NSKeyedUnarchiver unarchiveObjectWithData:readData];
    }
 
    // test用 
    newCheck_ = [NSNumber numberWithInt:1];
    favoraite_ = [NSNumber numberWithInt:1];
    
    NSLog( @"A %@ %@ ", newCheck_, self.favoraite_ );
    
}
 
-(void)writeData:(NSString*)path{
 
    NSData* writeData = [NSKeyedArchiver archivedDataWithRootObject:self];
 
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:writeData forKey:path];
    [defaults synchronize];
    
}
 
@end

@interface TestObj
@end

@implementation TestObj
int main() {
	struct {
		int row;
	} indexPath;
	NSNumber *newCheck_ = [[NSNumber alloc] initWithInt:1];
	struct {
		NSNumber *favoraite_;
	} self;
	indexPath.row = 346;
	self.favoraite_ = [[NSNumber alloc] initWithInt:1];

	// 実装部分
	MyObject *myObj = [[MyObject alloc] init];
	NSString *path = [NSString stringWithFormat:@"DATA_%03d", (int)indexPath.row];
	[myObj readData:path];
	NSLog( @"B %@ %@ ", newCheck_, self.favoraite_ );

	return 0;
}
@end
実行結果

コード:

2015-02-26 01:26:33.970 prog[352] autorelease called without pool for object (96846e0) of class GSCInlineString in thread <NSThread: 0x9652798>
2015-02-26 01:26:33.971 prog[352] autorelease called without pool for object (968ae90) of class NSUserDefaults in thread <NSThread: 0x9652798>
2015-02-26 01:26:33.971 prog[352] autorelease called without pool for object (9682740) of class GSArrayEnumerator in thread <NSThread: 0x9652798>
2015-02-26 01:26:33.971 prog[352] A 1 1 
2015-02-26 01:26:33.971 prog[352] B 1 1 
https://ideone.com/EdHoAU
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

山田

Re: Objective-Cでの独自クラスについて

#3

投稿記事 by 山田 » 9年前

みけCAT さん

回答ありがとうございます!
こちら、クラス自体は間違ってないということでしょうか?

原因が謎すぎて・・・引数の値を変えてるだけだからかなーとか
(ポインタっぽいもので管理してるはずなのでそれも違いそう)

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: Objective-Cでの独自クラスについて

#4

投稿記事 by h2so5 » 9年前

「実装部分」はどこに書いてあるのですか?

閉鎖

“C言語何でも質問掲示板” へ戻る