アプリ版:「スタンプのみでお礼する」機能のリリースについて

Objective-Cであるクラスから、特定のViewControllerのもつLabel要素へテキストを表示したく、色々試してみたのですが、うまく動作しませんでした。
詳しい方、ぜひアドバイスお願いします。

□やりたいこと
クラス側から、ViewControllerの持つ要素を操作したい

□テストで使用したコード
test_buttonをクリックすると、lbl_mesへ文字列を表示する

-----------------
■classTest.h
#import "helloViewController.h"
-----------------
■classTest.m
#import "classTest.h"
- (void) makeStr {
helloViewController *hv = [[helloViewController alloc] init];
hv->lbl_mes.text = @"HELLO WORLD";
[hv release];
}
-----------------
■helloViewController.h
#import "classTest.h"
@interface helloViewController : UIViewController {
@public
IBOutlet UILabel* lbl_mes;
}
@property(nonatomic,retain) IBOutlet UILabel* lbl_mes;
-(IBAction) test_button;
-----------------
■helloViewController.m
#import "helloViewController.h"
-(IBAction) test_button{
classTest *clst = [[classTest alloc] init];
[clst makeStr];
[clst release];
}

よろしくお願いします。

A 回答 (2件)

改訂後のプログラムは、打って変わって90点のできですね。

すばらしいです。

なお、100点に足りない10点分の説明をしておきます。

- (void)dealloc {
[super dealloc];
[share_string release];
}

「[super dealloc]」は、すべてのインスタンスの開放をしたのち、最後に行います。「init」(初期化)のときとは、逆の処理をするのですね。

share_string = @"HELLO WORLD";

この形で生成したNSStringインスタンスは、開放する必要がありません。NSStringは、すこし特殊なクラスです。これは「オブジェクト定数」といって、元のインスタンスが存在している間じゅう、開放されずに残ります。「#define」で宣言した定数のように扱えます。
    • good
    • 0
この回答へのお礼

harawoさん、改訂版の採点までしていただきありがとうございます! 結構いい点数をもらえてちょっと安心しました。(ちょっと不安でしたw)
残りの10点分の指摘もすごく勉強になり、本当に感謝です。ありがとうございました!

お礼日時:2011/02/07 18:43

問題点はひとつだけではない(というか、まともな行のほうが少ない)し、すべて指摘することはできない(しようとするなら、有料にせざるを得ない)ので、ざっとだけ列挙してみます。



まず、直接関係ない、訂正しなくてもかまわないが、いま矯正しておかないと、将来延々と困ったことになることについて:
(1) クラス名は大文字で始める規則になっています。べつに小文字で始めても,コンパイルは通りますが、インスタンスを代入した変数と区別ができないため、致命的なミスを引き起こす要因になります。クラス名は大文字で始め、インスタンスを代入した変数を含め、変数名は小文字で始める規則になっています。
(2) 別インスタンスから、インスタンス変数の参照(hv->lbl_mes)は、Objective-Cの文法上できることになってますが、じっさいに使うことはありません。その代わりにプロパティを使うからです。ましてや、インスタンス変数の参照とプロパティの参照を、同時に行うことなど、混乱を引き起こすだけで、メリットはありません。
(3) 「IBOutlet」、「IBAction」は、Interface Builderと連携するときに使用する、目印であって、Interface Builderなしでプログラムするときには不用です。コンパイル時、IBOutletはスペースに、IBActionはvoidに置換されます。また、IBOutletの宣言は、インスタンス変数か、プロパティのいずれかひとつで行えばいいのであって、二度以上宣言する必要はありません。

つぎに、重大な問題について:
(1) UIViewController(とそのサブクラス)のViewは、生成しただけでは、画面に表示されません。親View(superview)かWindowに「addSubview」することで、初めて表示されます。
(2) インスタンスを生成したら、いつか開放(release)しなければならないのは、そのとおりです。が、確実にそのインスタンスが使われないという保証がないのに、とうめん用が終わったからといって、開放してはいけません。開放は、NSObject(すべてのクラスのスーパークラス)のメソッド「dealloc」で行うといいでしょう。

そして、このプログラムの抱えている矛盾について:
helloViewControllerのインスタンス内で、classTestのインスタンスclstを生成し、clstのメソッドmakeStrで、helloViewControllerのインスタンスを生成しています。では最初のhelloViewControllerインスタンスと、最後のhelloViewControllerインスタンスの関係は?同一のインスタンスにはなりません。べつべつのインスタンスです。
    • good
    • 0
この回答へのお礼

harawoさん、ご指摘ありがとうございました。
曖昧なまま根本的な所が間違っていたままテストしていたことに気づかされ、harawoさんのアドバイスを踏まえながら、基本を見直してみました。

まだ、おかしな点も多いかもしれないですが、下みたいに変更し、プロパティを用いてラベルに値を表示することができました。

まだ曖昧な部分も多いので、色々と勉強してみます。ありがとうございました!

-----------------
■ClassTest.h
@interface ClassTest : NSObject {
NSString *share_string;
}
@property(nonatomic,retain) NSString *share_string;
- (void) makeStr;

-----------------
■ClassTest.m
#import "ClassTest.h"
@implementation ClassTest
@synthesize share_string;

- (void) makeStr {
share_string = @"HELLO WORLD";
}

- (void)dealloc {
[super dealloc];
[share_string release];
}

-----------------
■HelloViewController.h
@interface HelloViewControllerViewController : UIViewController {
IBOutlet UILabel* lbl_mes;
}
-(IBAction) test_button;

-----------------
■HelloViewController.m
#import "HelloViewControllerViewController.h"
#import "ClassTest.h"
@implementation HelloViewControllerViewController

-(IBAction) test_button{
ClassTest *classTest = [[ClassTest alloc] init];
[classTest makeStr];
lbl_mes.text = classTest.share_string;
[classTest release];
}

お礼日時:2011/02/07 17:01

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!