Objective-Cのメモリ管理についての疑問

このQ&Aのポイント
  • Objective-Cのメモリ管理に関する疑問について解説します。
  • retainCountの値が異なる理由について説明します。
  • 「self.」を付けることでretainCountが変化する仕組みについて詳しく説明します。
回答を見る
  • ベストアンサー

Objective-Cのメモリ管理

はじめまして。 iphoneアプリを作っていてメモリ管理について不明な点があるので教えて下さい。 memoryViewController.h ============================================== #import <UIKit/UIKit.h> @interface memoryViewController : UIViewController { id obj; } @property(retain)id obj; @end =============================================== memoryViewController.mm(一部) =============================================== @implementation memoryViewController @synthesize obj; - (void)viewDidLoad { [super viewDidLoad]; self.obj = [[NSObject alloc] init]; NSLog(@"count = %d", [obj retainCount]); } =============================================== 下記の部分についてです。 self.obj = [[NSObject alloc] init]; 「self.」を付けた場合retainCountは2で、付けなかった場合retaionCountは1になります。 何故違ってくるのかが理解できません。 教えて下さい。

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

  • ベストアンサー
  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.1

self を付けるとsetterを通して値が設定されるから。 そして件の obj は retain。 だから2

その他の回答 (2)

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.3

No.2の訂正です。 この「(retain)」を外してみてください。→ この「(retain)」を、「(assign)」に書き換えてみてください。

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.2

宣言部 @property(retain)id obj; この「(retain)」を外してみてください。プロパティの宣言で、retainのオプションを付加することで、Retain Countが増加することがわかります。 ※ > memoryViewController.mm 拡張子.mmは、Objective-C++(Objective-CとC++のブリッジ)に使用する実装ファイルの拡張子ですが、それで合ってます?

bad_star
質問者

補足

.mmは入力ミスです。ありがとうございます。

関連するQ&A

  • Objective-C,viewが動作しない

    IBを使わないカメラアプリを作っています。 AppDelegate.m内のapplication didFinishLaunchingメソッド内で生成したwindowとviewはコンパイルして表示確認できたのですが、viewControllerで書いたUIImagePickerViewControllerのviewが出てきません。 そもそもviewController.mのloadViewメソッドやviewDidLoadメソッドが動いていません。(メソッド内にNSLogを書いてコンパイルしてもログに出ない) viewController.h #import <UIKit/UIKit.h> @interface CameraViewController : UIViewController <UINavigationControllerDelegate,UIImagePickerControllerDelegate> { @private UIImagePickerController* _imagePicker; } @property(nonatomic,retain) UIImagePickerController *imagePicker; @end viewController.m #import "CameraViewController.h" @implementation CameraViewController @synthesize imagePicker=_imagePicker; - (void)dealloc { [super dealloc]; } #pragma mark - View lifecycle - (void)loadView { [super loadView]; //UIImagePickerControllerの作成 if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){ return; } UIImagePickerController* imagePicker; imagePicker = [[UIImagePickerController alloc] init]; [imagePicker autorelease]; imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; imagePicker.allowsEditing=NO; imagePicker.delegate = self; //imagePickerのviewを最上部に [self presentModalViewController:imagePicker animated:YES]; //シャッターを切る [self.imagePicker takePicture]; } @end viewControllerが機能しない原因としてそういった可能性が考えられるのでしょうか? あれこれ調べてみましたが煮詰まっています。よろしくお願いします

  • 【Objective-C】プロパテイについて

    Objectiv-Cの勉強を始めたばかりの者です。 プロパテイの機能を理解する為に以下のようなプログラムを書きました。 例1)まずは、プロパテイを使わない例です。 ーーーーーーー data.h ーーーーーーー #import <Foundation/NSObject.h> #import <Foundation/NSString.h> @interface Data : NSObject { NSString* str; } - (void)setStr:(NSString* )arg; - (NSString*)retStr; @end ーーーーーーー data.m ーーーーーーー #import "Data.h" @implementation Data - (NSString*) retStr{ return str; } - (void)setStr:(NSString*) arg{ [arg retain]; [str release]; str = arg; } @end ーーーーーーー main.m ーーーーーーー #import <stdio.h> #import "Data.h" int main(void) { Data* data = [[Data alloc] init]; [data setStr:@"aaa"]; NSLog(@"%@",[data retStr]); return 0; } 例2)次に、プロパテイを使って例1を書き換えてみました。 ーーーーーーー data.h ーーーーーーー #import <Foundation/NSObject.h> #import <Foundation/NSString.h> @interface Data : NSObject { NSString* str; } @property (retain) NSString* str; @end ーーーーーーー data.m ーーーーーーー #import "Data.h" @implementation Data @synthesize str; @end ーーーーーーー main.m ーーーーーーー #import <stdio.h> #import "Data.h" int main(void) { Data* test = [[Data alloc] init]; test.str = @"hoge"; NSLog(@"%@",test.str); return 0; } 例2を実行した結果、以下のように出力されました。 2010-02-05 22:17:50.696 data[1583:903] *** __NSAutoreleaseNoPool(): Object 0x100001068 of class NSCFString autoreleased with no pool in place - just leaking 2010-02-05 22:17:50.698 data[1583:903] hoge @propertyのオプションを(retain) ではなく、(assign)に変更すると、 2010-02-05 22:30:02.271 data[1619:903] hoge と出力されて、期待した結果が得られるのですが、なぜretainではダメなのでしょう? また、assignでも例1のようなメモリ管理は自動的に行われているのでしょうか? 以上、ご指導の程、よろしくお願いいたします。

  • Objective-Cの参照カウンタの質問です。

    Objective-Cの参照カウンタの質問です。 最近iPadの開発を始めた初心者です。 よろしくお願いします。 <質問1> 以下のようなサンプルを動作せさました NSObject *obj = [[NSObject alloc] init]; NSLog( @"A cnt %d", obj.retainCount); [obj release]; NSLog( @"B cnt %d", obj.retainCount); NSLog( @"C cnt %d", obj.retainCount); 以下のようにデバッガコンソールには表示されます 2010-08-15 11:41:45.711 MemoryTest[2087:207] A cnt 1 2010-08-15 11:41:45.756 MemoryTest[2087:207] B cnt 1 プログラムはシグナルを受信しました:“EXC_BAD_ACCESS”。 NSLog( @"B cnt %d", obj.retainCount);を実行する前にreleaseしているので、 "B cnt 1"は表示されず、:“EXC_BAD_ACCESS”が表示されるべきと思うのですが、 なぜ、このようになるのでしょうか? <質問2> 以下のようなサンプルを動作せさました NSObject *obj = [[NSObject alloc] init]; NSLog( @"A cnt %d", obj.retainCount); [obj release]; obj = nil; NSLog( @"B cnt %d", obj.retainCount); NSLog( @"C cnt %d", obj.retainCount); 以下のようにデバッガコンソールには表示されます 2010-08-15 11:45:32.151 MemoryTest[2122:207] A cnt 1 2010-08-15 11:45:32.162 MemoryTest[2122:207] B cnt 0 2010-08-15 11:45:32.165 MemoryTest[2122:207] C cnt 0 NSLog( @"B cnt %d", obj.retainCount);を実行する前にreleaseしているので、 「B]と「C」は表示せず、:“EXC_BAD_ACCESS”が表示されるべきと思うのですが、 obj = nil;の実行だけで、なぜ、このようになるのでしょうか? obj = nilはポインタをクリアするだけで、releaseの実行と関係ないと考えています。 よろしくお願いします。

  • Obj-Cで生成元のViewへ文字列を表示させたい

    iOS SDK(Objective-C)を勉強中なのですが、あるView(TestViewController.view)から別のView(ButtonViewController.view)を表示し、表示したViewにあるボタンを押した時に、生成元のView(TestViewController.view)のラベル(test_label)に文字列を表示したいのですが、色々やってみたものの上手く行かず、どの用に実装するのが正しいのか行き詰まってしまいました。どなたか手助けよろしくお願いします。 //*** TestViewController.h #import <UIKit/UIKit.h> #import "ButtonViewController.h" @interface TestViewController : UIViewController { IBOutlet UILabel *test_label; ButtonViewController *buttonViewController; } - (IBAction) pushButton:(id)sender; @end //*** TestViewController.m #import "TestViewController.h" @implementation TestViewController - (void)viewDidLoad { [super viewDidLoad]; test_label.text = @"Push Button"; } //ButtonViewを表示 - (IBAction) pushButton:(id)sender { buttonViewController = [[ButtonViewController alloc] initWithNibName:@"ButtonView" bundle:nil]; [self.view addSubview:buttonViewController.view]; } - (void)dealloc { [buttonViewController release]; [super dealloc]; } @end //*** ButtonViewController.h #import <UIKit/UIKit.h> @interface ButtonViewController : UIViewController { } - (IBAction) pushButtonSub:(id)sender; @end //*** ButtonViewController.m #import "ButtonViewController.h" @implementation ButtonViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction) pushButtonSub:(id)sender { // ??? ← このボタンを押したときにtest_labelへ表示させたい } - (void)dealloc { [super dealloc]; } @end

  • objective-C(Xcode)に関して質問があります。

    objective-C(Xcode)に関して質問があります。 新規プロジェクトからview-base Applicationテンプレートを使用してプロジェクト(TestClass.xcodeproj)を作成します。 そうすると、TestClassAppDelegate.m, TestClassAppDelegate.h, TestClassViewController.h, TestClassViewController.mが Classesフォルダーに作成されます。このプロジェクトに自分で作成するクラス(MyTestClass)を追加するにはどうすれば良いのでしょうか? 下記のコードではエラーはでませんが、tc.counterにint 10が代入さず、0(nil)が出力されます。 (interfacebuilder でボタンのみ設置、ボタンを押すとpushが呼ばれ、logを残す) ===MyTestClass.h===== #import <Foundation/Foundation.h> @interface TestClass : NSObject { int counter; } @property int counter; @end ===MyTestClass.m===== #import "TestClass.h" @implementation TestClass @synthesize counter; -(int)calcPlus{ return counter = counter+10; } @end ===TestClassViewController.h==== #import <UIKit/UIKit.h> #import "TestClass.h" @interface TestClassViewController : UIViewController { TestClass *tc; } -(IBAction) push; -(void)calc; @end ===TestClassViewController.m=== #import "TestClassViewController.h" #import "TestClass.h" @implementation TestClassViewController -(IBAction)push{ tc.counter = 10; NSLog(@"%d", tc.counter); } サンプルコード(iPhoneUnitTests ((calc)))をみても、特別なことはなく、ヘッダーの読み込みさえ出来てれば クラスが使えそうなのですが・・・。 コメントをいただければ、幸いです。

  • 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 初心者です

    はじめまして。iphone アプリ開発を始めようと思い、まずは簡単なアプリからと人のまねをして時計アプリを書いております。http://www.slideshare.net/takuya0429/121216の43枚目のスライドを丸写しにしました。しかし、iPhoneシミュレーター(iphone 6.1)でシミュレーションしても真っ黒な画面が移されるだけで思うように機能しません。 なぜ機能しないかを考えられる範囲でご教授願いたい次第です。 環境はmacbook air 13inch にてXcode 4.6.3を使用しております。 以下に作成したコードを記載いたします。 // // ViewController.h // watch // // Created by motoyama kaoru on 2013/08/15. // Copyright (c) 2013年 motoyama kaoru. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *timeLabel; @end // // ViewController.m // watch // // Created by motoyama kaoru on 2013/08/15. // Copyright (c) 2013年 motoyama kaoru. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(update) userInfo:nil repeats:YES]; } -(void)update{ NSDate *now = [NSDate date]; NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setDateFormat:@"HH:mm:ss"]; self.timeLabel.text = [df stringFromDate:now]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end

  • Objective-c  画面遷移について

    毎回、初歩的な質問内容で申し訳ありませんが、困っているので教えて下さい。 「FirstViewController」はUIScrollViewでスクロールさせている画面で、タッチイベントを取得する為に UIScrollView のサブクラスを作っています。 そこでタッチすると、「SecondViewController」へ固定の画面で遷移するようにしたいのですが、「SecondViewController」の画面もそのままスクロール画面で表示されてしまいます。。。 「SecondViewController」をスクロールさせず、位置x=0 y=0で表示させるにはどうしたら良いのでしょうか? 詳しく教えて頂けると、大変助かります。。 ↓FirstViewController.h↓ @interface FirstViewController : UIViewController{   MyScrollview *controller; IBOutlet UIScrollView *scrollView; } ↓FirstViewController.m↓ - (void)viewDidLoad { controller = [[ MyScrollview alloc] initWithFrame:CGRectMake(0, 0, 1100, 1100)]; self.view = controller; [super viewDidLoad]; [super loadView]; scrollView.contentSize = controller.frame.size; [scrollView addSubview:controller]; } ↓MyScrollview .h↓ @interface MyScrollview : UIView<UIScrollViewDelegate>{ } @end ↓MyScrollview .m↓ -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ SecondViewController *svc; svc = [[SecondViewController alloc] init]; [self addSubview:[svc view]]; }

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

    objectiv-cの勉強を始めたばかりです。ネットで調べながら進めているのですが、プロジェクト内のテキストファイルではなく、サーバにあるテキストファイルの内容を読み込み、NSLogに出力しようとしているのですが、うまくいきません。xxxxxxxxxxxの部分にテキストファイルのあるURLを入れています。 -----------------textloadViewController.h------------------------------ #import <UIKit/UIKit.h> @interface textloadViewController : UIViewController @end -----------------textloadViewController.m------------------------------ #import "textloadViewController.h" @interface textloadViewController () @end @implementation textloadViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. NSError *error = nil; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"xxxxxxxxxxx" ofType:@"txt"]; NSString *string = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error]; NSLog(@"%@", string); } @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 毎秒タイムスタンプは出力されませんでした。 以上、ご指導の程、よろしくお願いいたします。

専門家に質問してみよう