Objective-Cでのselfとは何者なのか?

このQ&Aのポイント
  • Objective-Cのselfは、自分自身を表す変数です。
  • selfは、インスタンスメソッド内で使用される隠し引数です。
  • selfは、オブジェクト自体を指し示し、そのオブジェクトのプロパティやメソッドにアクセスするために使われます。
回答を見る
  • ベストアンサー

Objective-Cでのselfについて。

初めまして。objective-Cの初心者で、「self」についての質問です。 「selfとは、自分自身を表す変数である。」と、様々なWebサイトや参考書に書いてあるのですが、いまいちピンときません。 例えば、target:selfとか、hoge.delegate=selfだとか、self.title=@"hoge"のようにselfが前に付いたり、後ろに付いたり、”:”だったり”=”だったり”self.”もしくは”.self”だったりでselfが何をしているのかが全く分かりません。 例えば@implementationの中の”Hoge{”内にあるtarget:selfという文があっても、「Hogeをターゲットにして自分(self)を呼び出して、一体何をしているんだ?」と考え込んでしまいます。 一体selfとは何者なのか(隠し引数だとか自分自身だとか、言葉は分かってるのですが)どなたか、ピンとくる回答をお願いいたします。「このselfさえ分かればもう、つまづく事は無い!」「このselfさえ攻略してしまえば...!」というところが、今の気持ちです。「これさえ分かれば」なのです。どうぞよろしくおねがいいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

オブジェクト指向という考え方は、プログラミングの中に現るものを「物」として扱い、それに対して、「メッセージ」を送ることで、処理を行おうという考え方です。 なので、基本は、「だれが」「だれに」「どのようなメッセージ(と、ついでに、パラメータ)」を送るか。 そして、メッセージの受け手は、「受けたメッセージに対してどういう反応を示すか」ということ。 たとえば、ドラマや芝居で、「この人物は、どのような言葉をかけられるとどう行動するか」ということを全部決めて、あとは、「スタート」と声をかけると、ドラマが勝手に進行する(処理が続行される)という考え方の上に成り立っているものです。 普通にドラマを作ろうとすると、始めから終わりまでシナリオを作らなければなりません。 それに対して、ある登場人物に対して、「誰それからこう言われたら、こういう反応をする」ということだけを決めるなら、一度に考えなければならないことが、少なくてすみます。だから、大きなシステムも比較的シンプルに構成できるだろうという発想です。 さて、「だれに」という要素が存在するのですが、メッセージというのは、自分以外の人に送ればそれですべてOKというものではありません。 「自分にメッセージを送ってください」と設定するとか(郵便.宛先 = 自分) 「自分のことを表明する」とか、(自分.名前 = 太郎) まあ、そういう文脈で、「自分」ということがあちこち出てくるわけです。 そういう、「物(人も)」と「メッセージ」で成り立つ世界において、「彼」や「彼女」や「あなた」と同じように、「自分自身」を表すものです。 で、自分自身の行動には、いちいち「自分はどうする」といわないように、「自分」というのがなくても、動作は記述できるのですが、本来、他人に当てたメッセージや他人のことも設定できるような部分に、「(他の人じゃなくて)自分」というのを明示するのに、 self が使われたりするわけです。

silvercpanda
質問者

お礼

ボンヤリとではありますが、なんとなく解ったような気がします。ありがとうございました。これからも精進していきます。

その他の回答 (2)

noname#190876
noname#190876
回答No.3

ギャラのでない、ここで、ながながした説明する気にはなりませんが、まじめに、Objective-Cのテキスト読んだことあるんでしょうか。よくあるのは、ネットにころがってある、いいかげんな説明をよんでわからん、とか言っていることですが。  Appleのドキュメントは、基本、英語ですが、Objective-Cについての説明は、日本語でありますけど、これ、読みました?

  • chie65535
  • ベストアンサー率43% (8525/19381)
回答No.1

>target:selfとか、hoge.delegate=selfだとか、self.title=@"hoge"のようにselfが前に付いたり、後ろに付いたり 前に付いたり後ろに付いたりの意味が判らないなら、ぶっちゃけ「基礎から勉強して来い」なんだけど。 >selfが何をしているのかが全く分かりません。 「何もしてない」が正解。 http://ja.wikipedia.org/wiki/This_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0) に解説されてる「this」と同じだから、上記ページをよく読むこと。 上記ページを読んでも理解できないなら、objective-Cなどの「オブジェクト指向言語」は理解できないから、他の言語を習得するか、プログラミングは諦めた方が身の為。

関連するQ&A

  • Objective-Cクラス変数インスタンス変数

    現在iPhoneアプリを作成するために、Objective-Cの勉強をしています。しかしそこでわからないことがあり、質問させていただきました。 それは私がインスタンス変数(メンバ変数)を宣言してつかっているつもりなのですが、クラス変数の様な動きをするのです。 具体的にコードで説明します。 @implementation Main : NSObject - (void)hello{ [[Hoge alloc]init]; [[Hoge alloc]init]; } @end @implementation Hoge : NSObject NSNumber *i; - (id)init{ [super init]; NSLog(@"%d",i.intvalue); i = [NSNumber numberWithInt:123]; return self; } @end 出力結果 null 123 今手元にソースがないので正確ではないかもしれませんが、こんな感じです。hファイルにはとくになにもかいてません。 このソースの動きはmainでHogeクラスのインスタンスを二回作成することによって、initを二回呼んでいます。 疑問点は出力結果の挙動が予想外なことです。私としてはインスタンス作成時のiは初期化されていないため、 出力結果 null null になるのを期待しています。しかし二回目のinitでは前回に作成した123というデータが引き継がれています。この挙動はiはインスタンス変数ではなく、クラス変数のようにみえます。 しかしObjective-Cではクラス変数は存在しないとどっかのサイトに書いていました。 以上が質問です。なにかお気づきになった点があればごかいとういただけると幸いです。

  • objective-cでの引数について

    お世話になります。 引数の使い方について以下の様な事が可能なのか分からなくて困ってしまい質問します。 検索等は行いましたが目的のものが見つからなかったので、、 以下ですが、あるボタンをタップすると、buttonDidPushを実行するプログラムがあったとします。 @implementation ViewController -(void)viewDidLoad{ ~中略~ [button addTarget: self action:@selector(buttonDidPush) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } -(void)buttonDidPush{    処理 } @end ここで聞きたいのは、 ボタンのところで、引数(数値変数 x )をbuttonDidPushに持っていくことができるかどうかなのですが、 例えば以下のように変更しました。 action:@selector(buttonDidPush) ↓ action:@selector(buttonDidPush:x:) -(void)buttonDidPush{ ↓ -(void)buttonDidPush(Integer)x{ としましたが、build successで一応シミュレータは動きましたが、 ボタンをタップするとmain.mのほうでエラーが出てしまい動きませんでした。 なんとなく文法が間違ってるんじゃないかと思いますが、どこか心当たりのある方、よろしくお願いいたします。 尚、数値xはintで宣言済みです。 main.mでのエラー内容は int retval = UIApplicationMain(argc, argv, nil, @"testAppDelegate"); のラインで、「Thread1:Program received signal: ""SIGABRT.」と出ていました。 また、私自身が何かobjective-cの文法について重大な勘違いをしている可能性もあります・・

  • [objective-C]配列について

    はじめまして。 objective-C、cocos2dについての質問です。 iPhoneアプリを勉強しながら作り始めたのですが詰まってしまい、できればご助力をお願いしたいと思い質問させていただきました。 cocos2dというフレームワークを使用し簡単なRPGを作りたいと考えております。 そこでキャラクターのステータスを配列に格納し、どのシーンからも参照したいのですが、どうしてもうまくいきません。 別クラスでインスタンス変数を作り、それを利用して配列を作成する方法で実装しようとしており、実際のコードは以下の通りになります。 ---------------------------------- <Character.h> @interface Character : NSObject{ NSInteger characterStateAtk_; ・(Def、Hpなど) ・ } @property (nonatomic, assign) NSInteger characterStateAtk;  ・  ・ @end <Character.m> #import "Character.h" @implementation Character @synthesize characterStateAtk = characterStateAtk_;  ・  ・ @end キャラクターステータス生成部分 <CreateScene.h> @interface CreateScene : CCScene { NSMutableArray* characterStateArray_; } @property (nonatomic, assign) NSMutableArray *characterStateArray; @end <CreateScene.m> @interface CreateScene() - (void) pressReloadButton:(id)sender; - (void) createCharacterState; @end @implementation CreateScene @synthesize characterStateArray = characterStateArray_; - (void) dealloc{ [self.characterStateArray release]; [super dealloc]; } - (void) createCharacterState{ self.characterStateArray = [NSMutableArray array]; Character* priState = [[[Character alloc]init] autorelease]; priState.characterStateAtk = random() % 5 + 5; ・ ・ [self.characterStateArray addObject:priState]; } (その他の処理) - (void) pressReloadButton:(id)sender{ [self createCharacterState];  (ここでcharacterStateArrayを取得して表示したい) } ---------------------------------- 最初は、 NSInteger x; x = [[self.characterStateArray objectAtIndex:0]intValue]; で取得しようとしたのですがエラーとなり実行できませんでした。 (調べていくうちにobjective-Cでは配列の中身はオブジェクトしか使えないという事を知りました) プログラム中の(ここでcharacterStateArrayを取得して表示したい)の部分について、実装方法や考え方についてご助言をいただけないでしょうか? よろしくお願いいたします。

  • Objective-c の変数の参照取得方法について

    メンバ変数とかの参照(アドレス)を取得するにはどうすれば良いのでしょうか? 下記のようなサンプルを書いてもコンパイルエラーになってしまいます。Objective-C ってCと記述が同じだと思っているので「&」演算子でアドレスが取れると思っていたのですが。。。 @interface AAA : NSView { } -(void) test:(NSRect *)rct; @end @implementation AAA -(void) test:(NSRect *)rct { NSRect *p = nil; if (nil == rct) p = &[self frame]; <- フレームのアドレスを取得したい else p = rct; } @end 以上 宜しくお願い致します。

  • Objective-C,NSTimerを使って1秒毎に10秒かかる処理

    Objective-C,NSTimerを使って1秒毎に10秒かかる処理を実行させる事ってできますか? 例えば、以下に書いたとすると、(行頭全角スペースです。) @interface testTimer : NSObject {  NSTimer *timer; } @end @implementation testTimer - (id) init { timer = [NSTimer scheduledTimerWithTimeInterval:1.0  target: self  selector:@selector(timeUpdate:)  userInfo:nil  repeats:YES]; } - (void) timeUpdate:(id)sender {  NSLog(@"%@",[NSDate date]);   [NSThread sleepUntilDate:[[NSDate date] addTimeInterval:10.0]]; } @end 毎秒タイムスタンプは出力されませんでした。 以上、ご指導の程、よろしくお願いいたします。

  • objective-cで困っています。

    objective-cをトライ&エラーで試しながら学習しているのですが、 下記の内容で行き詰っており、知恵をお借りしたいと思い投稿しました。 現在tml5のcanvasを使ってお絵描きアプリを作りました。このcanvasに書き込んだデータをiPhoneのカメラロールに保存することをトライしています。いろいろ調べてみると「HTML5 CANVASの描画内容をUIImage経由でカメラロールに保存する」という記事をみつけました。http://lab.spec5zigen.com/archives/html5-canvasの描画内容をuiimage経由でカメラロールに保存する/ その記事を参考に #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // UIWebViewのインスタンス化 CGRect rect = self.view.frame; UIWebView *webView = [[UIWebView alloc]initWithFrame:rect]; // Webページの大きさを自動的に画面にフィットさせる webView.scalesPageToFit = YES; // デリゲートを指定 webView.delegate = self; // URLを指定 NSURL *url = [NSURL URLWithString:@"http://xxxxxxxxxxxxxxxxxxxxxx"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // リクエストを投げる [webView loadRequest:request]; // UIWebViewのインスタンスをビューに追加 [self.view addSubview:webView]; } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if(![[request.URL.scheme] isEqualToString:@"sp5canvas2app"]){ return YES; } NSString * requestString = [[request URL] absoluteString]; NSArray *params = [requestString componentsSeparatedByString:@"data:image/png;base64,"]; // dataFromBase64String // NSData+Base64 Copyright 2009 Matt Gallagher. All rights reserved. // http://www.cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html NSData * decodedData = [NSData dataFromBase64String:[params objectAtIndex:1]];//decode base64 to NSData UIImage *image = [UIImage imageWithData:decodedData]; UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);//カメラロールに保存 return NO; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end としてみたのですが、 if(![[request.URL.scheme] isEqualToString:@"sp5canvas2app"]){ の行にExpected identifierというエラーが、 NSData * decodedData = [NSData dataFromBase64String:[params objectAtIndex:1]];の行にNo known class method for selector 'dataFromBase64String:'というエラーが という状況で詰っている状況です。 メソッドの定義や宣言されていないメソッドを使っているなどのエラーということを調べて分かったのですが、objective-cを始めたばかりで初歩的なミスかも知れませんがエラーの対応の仕方がまだまだよくわかっていません。 スキーマなど参考にしたサイトの内容も十分に理解しているのではないのですが、「sp5canvas2app」の部分は自由に変えていいのでしょうか? 解決の仕方を教えていただけないでしょうか? 宜しくお願いします。

  • objective-cで困っています教えてください

    objective-cをトライ&エラーで試しながら学習をしている初心者です。タッチした所を中心にまず100×100の正方形を表示し、その後スライダーで正方形の大きさを決めてから画像のトリミングをしたいのですが、正方形が表示されないのと、タッチした位置と切り取られる位置がずれています。上記の内容で行き詰っており、知恵をお借りしたいと思い投稿しました。宜しくお願いします。 ViewController.mの内容 #import "ViewController.h" @interface ViewController (){ // UILabel *label; // UIImageView *uv; //中心の位置 float v; // X座標 float x; // Y座標 float y; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //写真の表示 CGRect rect_uv = CGRectMake(0,20, 360, 360); UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect_uv]; //画像のアスペクト比を維持しUIImageViewサイズに収まるように表示 imageView.contentMode = UIViewContentModeScaleAspectFit; UIImage *image = [UIImage imageNamed:@"hoge.png"]; [imageView setImage:image]; [self.view addSubview:imageView]; // UISliderのインスタンス化 CGRect rect_sd = CGRectMake(50, 400, 200, 10); UISlider *slider = [[UISlider alloc]initWithFrame:rect_sd]; // スライダーの最小値,最大値,値を設定 slider.minimumValue = 0; slider.maximumValue = 500; slider.value = 100; // スライドしている最中に値を調べられるようにする.デフォルトでYESだがサンプルのため slider.continuous = YES; // スライダーの値が変更されたときに呼ばれるメソッドを設定 [slider addTarget:self action:@selector(slider_ValueChanged:) forControlEvents:UIControlEventValueChanged]; // スライダーをビューに追加 [self.view addSubview:slider]; // ラベルの設置 CGRect rect_lb = CGRectMake(300, 400, 100, 30); label = [[UILabel alloc]initWithFrame:rect_lb]; [self.view addSubview:label]; // 標準ボタン例文 UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame = CGRectMake(50, 450, 100, 30); [btn setTitle:@"切り取り" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(trim:) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:btn]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * スライダーの値が変更されたとき */ - (void)slider_ValueChanged:(id)sender { UISlider *slider = sender; // スライダーの値をログに記述 NSLog(@"スライダーの値:%f", slider.value); // ラベルのテキストを設定 //float v = slider.value; v = slider.value; label.text = [NSString stringWithFormat:@"%2.f",v]; //四角形を描画 CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 CGContextStrokeRect(context, CGRectMake(x,y,v,v)); // 四角形の描画 } /** * タッチされたとき */ - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.anyObjectメソッドでいずれか1つのタッチを取得 // 2.locationViewメソッドで対象となるビューのタッチした座標を取得 CGPoint p = [[touches anyObject] locationInView:self.view]; x = p.x; // X座標 y = p.y; // Y座標 NSLog(@"タップ開始 %f, %f", x, y); //四角形を描画 CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 CGContextStrokeRect(context, CGRectMake(x,y,100,100)); // 四角形の描画 } /** * 切り取りボタンが押されたとき呼ばれるtrimメソッド */ -(void)trim:(UIButton*)button{ // ここに何かの処理を記述する // (引数の button には呼び出し元のUIButtonオブジェクトが引き渡されてきます) // 切り抜き元となる画像を用意する。 //UIImage *srcImage = /* UIImagePickerなどから取得したUIImage */ UIImage *srcImage = [UIImage imageNamed:@"hoge.png"]; // 切り抜く位置を指定するCGRectを作成する。 CGRect trimArea = CGRectMake(x, y, v, v); // CoreGraphicsの機能を用いて、 // 切り抜いた画像を作成する。 CGImageRef srcImageRef = [srcImage CGImage]; CGImageRef trimmedImageRef = CGImageCreateWithImageInRect(srcImageRef, trimArea); UIImage *trimmedImage = [UIImage imageWithCGImage:trimmedImageRef]; // 画像表示例文 //UIImage *img = [UIImage imageNamed:@"hoge.png"]; UIImageView *iv = [[UIImageView alloc] initWithImage:trimmedImage]; [self.view addSubview:iv]; } @end

  • Objective-C グローバル変数 値変更反映

    当方、Objective-Cに関して1年にも満たない経験を持つ初心者です。 初歩的な内容だとは思いますが行き詰まってしまったため質問させて下さい。 複数の.hと.mファイルで定義された複数クラス間で一つの変数を共通で利用し、あるクラスのメソッド内で値を変更した際にそれ以外のクラスですぐに反映出来る様にしたいのですが、どの様に書いても値が反映されず初期値のまま出力されてしまいます。恐らく各クラス内のメソッドが呼ばれる順番に起因すると思うのですが、上手く解決出来ません。 現在書いているコードとして、 -xxxAppDelegate.h (at)interface xxxAppDelegate : NSObject <UIApplicationDelegate> { ... int globalNum; } (at)property(nonatomic, assign)int globalNum; (at)end -xxxAppDelegate.m ... (at)implementation xxxAppDelegate (at)synthesize globalNum; ... (at)end -A.h ... (at)interface AController : UIViewController { xxxAppDelegate *appDelegate; } ... -(void)changeNum; -(IBAction)changeController; (at)end -A.m ... (at)implementation AController ... - init(){ appDelegate = (xxxAppDelegate *)[[UIApplication sharedApplication] delegate]; } ... -(void)changeNum{ //ここでglobalNumの値を変更; appDelegate.globalNum=...; } ... //配置したボタンを押すとA->BにviewControllerを切り替える -(IBAction)changeController{ BController *B = [[BController alloc] initWithNibName:(at)"BController" bundle:nil]; B.modalTransitionStyle = UIModalTransitionStyleCoverVertical; [self presentModalViewController:B animated:YES]; [B release]; } ... (at)end -B.h ... (at)interface BController : UIViewController { xxxAppDelegate *appDelegate; } ... -(void)readNum; (at)end -B.m ... (at)implementation BController ... - init(){ appDelegate = (xxxAppDelegate *)[[UIApplication sharedApplication] delegate]; } ... -(void)readNum{ //globalNumの値を見る; NSLog((at)"%d" , appDelegate.globalNum); } ... (at)end となっています。( (at)=アットマークです。 ) xxxAppDelegateおよびxxxViewControllerよりAControllerを呼び出し、AクラスのchangeNumメソッドでglobalNumの値を変更した後、ボタンを押下してviewControllerをBControllerに切り替え、Bクラス内のreadNumメソッドでglobalNumの値を確認すると、変更が反映されていない事が分かります。 この方法以外にも色々と試してみたのですが、すっきりとしたコードが書けず、解決に至りませんでした。 申し訳ありませんが、皆さんの知恵をお貸し下さい。 よろしくお願いします。

  • [Objective-C] 連番スプライト定義

    こんにちは。 Objective-CのCocos2dフレームワークで簡単なテスト用アプリを製作中なのですが、 以下の様なスプライト定義をs1.png、s2.png、s3.png、s4.png、・・・といった連番画像でそれぞれで行いたいと考えています。 //■■■ レイヤーAを作成 ■■■ CCLayer *layerA = [CCLayer node]; [self addChild: layerA]; CGSize winSizeSprite = [[CCDirector sharedDirector] winSize]; //スプライトS1を生成 CCSprite *sampleSpriteS1 = [CCSprite spriteWithFile:@"s1.png"]; sampleSpriteS1.position = CGPointMake(winSizeSprite.width/2, winSizeSprite.height/2);   ・   ・   ・ [layerA addChild:sampleSpriteS1];//レイヤーAに追加 この「スプライト定義」から「レイヤー追加」までの処理を大量の画像について一括で行いたい場合、for文などを使用して条件式のiの値をファイル名やインスタンス変数の「S●」の部分に利用出来そうな気がするのですが、ダイレクトな説明の載っている参考書やWEBサイトが見つからず、具体的な記述法がわかりません。 当方、PHPについては多少の編集経験があるのですが、プログラミングについてはObjective-Cが初めてです。 上記記述法ご存知の方、ご教示頂けませんでしょうか。 宜しくお願い致します。

  • リファレンスの機能

    リファレンスではサブルーチンとして呼び出すライブラリ自体を変数に格納することができるのでしょうか?その概念がよくわかりません。たとえば HOGE.plというプログラムがあり、 (1)use INILOAD; (2)$HOGE::INI = new INILOAD inifile=>'CONFIG.ini'; (3)($ret, $MESS, $s) = $HOGE::INI->load; このloadがどこのことなのか、を調べているうちにINILOAD.pmのなかにあることがわかったのです。 そこで(3)をとおった時点で$HOGE::INIの中身をlogで確認したら INILOAD=HASH(0x1857b04) が格納されていました。これってINILOAD.pmそのものを格納しているということでしょうか?だとすると上記文でなぜ$HOGE::INIのなかに ライブラリ名が格納されるのですか? 最後にINILOAD.pmのnewを記載します。 sub new { my($class) = shift; my($args) = {@_}; &init(); bless { INIFILE => $args->{inifile} || 'default.ini', }, $class; } sub init { my($self) = shift; $self->{STATUS} = 0; $self->{STATUS_MESS} = 'undefined'; undef $self->{DATA}; } おそらくbless以下の部分がキーになるのかとは思いますが、私の理解は 『ハッシュの引数の値をkey:inifile,値'default.ini'としてこのプログラム上で読めるようにし、それに$classを付加したものをINIFILE というグローバルな変数に代入する』 なのですが、どうもしっくりきません。ご指摘よろしくお願いいたします。

    • ベストアンサー
    • Perl