ゆるい感じのプログラムを書きたい。

プログラムの敷居を下げて、多くの人が開発出来るように色々書いていきます!

【iPhoneアプリ】インスタンスとメモリー管理について

本当は、プロパティ「@proerty」の使い方を書くつもりでしたが...

まず最初に「インスタンス」の仕組みを書かないと、書いてる本人が
わからなくなりそうだったので、この題目にしました。

今回は、「インスタンスとメモリー管理」についてです。

まず、プログラム上で使われるメモリーの種類について
細かいと事を省いて、論理的に4種類あります。

▼プログラム領域
プログラムコードが格納されている。
▼静的領域
グローバル変数、static変数が格納されている。
▼スタック領域
自動変数、メソッドの引数、メソッドの戻り番地が格納されている。
▼ヒープ領域(利用出来るサイズが大きい)
インスタンス(alloc)を行ったインスタンス変数が格納されている。


この中で今回、お話しするのが
スタック領域」「ヒープ領域」になります。

では、クラスを作成し、インスタンスを行うまでの過程で、どのようにメモリーが
使われるのかを記載したいと思います。


▼まず、以下のコードでクラスを作成します。


ヘッダーファイルの変数宣言はこのような感じにします。
LaboObject.h

@interface LaboObject : NSObject

    @private NSString *labo1;
    @private NSString *labo2;
    @public  NSString *laboA;
    @public  NSString *laboB;

@end


次に、モデルファイルのメソッド実装はこのような感じにします。
LaboObject.m

@implementation LaboObject
    
+(NSString*)laboMethod1{
    NSString *labo1 = @"labo1";
    return labo1;
}

+(NSString*)laboMethod2{
    NSString *labo2 = @"labo2";
    return labo2;
}

-(NSString*)laboMethodA{
    return laboA;
}

-(NSString*)laboMethodB{
    return laboB;
}
    
@end


このプログラムをイメージで表すと下記の感じになります。
注意 変数名とメソッド名は違います

f:id:kassans:20140226190648p:plain

▼次に、このクラスをインスタンスすると
メモリーはどのように格納されるのかを説明します。


以下のコードでインスタンスします。

//インスタンス
LaboObject *Class = [[LaboObject alloc] init];


インスタンスを実行すると以下の図のように「ヒープ領域」に変数が格納されます。

f:id:kassans:20140226203501p:plain


また、次のように2回インスタンスを実行してみます。

//インスタンス 1個目
LaboObject *Class1 = [[LaboObject alloc] init];
//インスタンス 2個目
LaboObject *Class2 = [[LaboObject alloc] init];


そうすると、メモリーの格納状況は以下のようにオブジェクト毎に格納されます。

f:id:kassans:20140226192356p:plain


後半は「メソッド」のメモリー格納状況などを記載します。

続きを読む

【Xcode5】iOS7とiOS6のSDKを共有する方法

今回はXocdeのSDKについてです。


iPhoneOS iOS6iOS7で大きく変わった点として、
画面が「フラットデザイン」になりました。


その事により、新しいXcode5をインストールして、
iOS7SDKで開発すると、iOS6で利用していたプロパティもしくは、メソッド
非推奨もしくはデザインが異なって表示される事象が出てきます。

上記の対応でiOS7に変更する際
一旦、iOS6SDKが使えるXcodeのバージョンに戻す必要が出てくると思います。


その時に、Xcode5のiOS7からiOS6SDKに変更出来、共有する方法が
ありますので記載します。

XcodeSDK共有化手順 ※前提として、既にXcode5にバージョンアップ済み

1.AppleDeveloperにて旧Xcodeをダウンロード

▼以下、URLページ内の「Xcode 4.6.x」をクリックし
Xcode 4.6.x.dmg」をダウンロードしてください。xの数字はどれでも構いません。

https://developer.apple.com/downloads/index.action 
注意、無ければページをめくってさがしてください。


2.ダウンロードしたXcode 4.6.xをMacにインストール

▼ダウンロードした、ファイルをクリック

▼ポップアップ画面の指示に従い、アプリケーションフォルダにXcodeをドラッグ&ドロップする。

▼その際、既存のXcodeに対して、ポップアップメッセージが出てくるので、
「両方とも残す」を選択する。

▼アプリケーションファイルに登録後、Xcode〜が作成されるので
既存のXcodeと区別するように名前を「Xcode4」に変更します。


3.Xcode 4.6.xのフォルダーをコピーする

手順2の後、Xcode 4.6.xの「PhoneOS6.1.sdk」をXcode 5にコピーします。

▼ターミナルを開きます。

Xcode 4.0.6「PhoneOS6.1.sdk」の場所は以下にあります。
/Applications/Xcode4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk

※無い場合は、別の場所に保存されている可能性がありますので検索してください。

▼Xcode5のコピー先は以下の通りです。
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/


▼以下のコマンドを実行し、コピーする。
cp -r /Applications/Xcode4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/
※青文字の部分が異なる方は適宜変更してください。


※ちなみに、私はアドミンユーザでないとコピーされませんでした。
もしコピーされない場合は、「suコマンド」でアドミンユーザになって試してください。


4.Xcode 5を起動させ、SDKの変更を行う。

Xcodeを起動(再起動)後、下記画像の場所でiOSの選択できますので
ここで「iOS6.1」に変更する。


f:id:kassans:20140224193242p:plain

【iphoneアプリ】iOS 7で非推奨になった AudioSession編

今回は、Audio系で利用する「AudioSession」についてです。

iOS 7から「AudioToolboxフレームワークの「AudioSession」クラス
非推奨となり、

それに代わり、「AVFoundationフレームワーク
AVAudioSession」クラスを利用する事になりましたので記載します。


今まで「AudioToolboxフレームワークの「AudioSession」を利用する際
以下のように記載していました。

//AudioSession利用開始
AudioSessionSetActive(YES);
    
//音声入出力クラス利用
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                            sizeof (sessionCategory),
                            &sessionCategory);

しかし、このままだとiOS 7のコンパイル設定しているXcodeでは、
注記扱いにされてしまいます。


その為、iOS 7対応として「AVFoundationフレームワークの「AVAudioSession
を利用し、以下の用に変更します。

//AVFoundationのインスタンス
AVAudioSession *audioSession = [AVAudioSession sharedInstance];

//カテゴリの設定
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

//AVFoundation利用開始
[audioSession setActive:YES error:nil];


また、「setCategory」は以下の項目の設定も可能なので、利用用途に応じて
変更してください。

//setCategory一覧

NSString *const AVAudioSessionCategoryAmbient;
//別アプリでオーディオ再生中にアプリを起動しても停止しない。

NSString *const AVAudioSessionCategorySoloAmbient;
//デフォルト設定 別アプリでオーディオ再生中にアプリを起動するとオーディオが停止する。

NSString *const AVAudioSessionCategoryPlayback;
//音楽再生用のアプリで利用

NSString *const AVAudioSessionCategoryRecord;
//入力のみで録音用に利用

NSString *const AVAudioSessionCategoryPlayAndRecord;
//Voip,チャット用にマイク入力と音声出力を行う際に利用

NSString *const AVAudioSessionCategoryAudioProcessing;
//再生や録音ではなくオフラインオーディオ処理を行う際に利用。

NSString *const AVAudioSessionCategoryMultiRoute;
//USBオーディオインターフェースやHDMIなどの外部出力を接続したときに
//ヘッドホンへ別系統の音を出力できる機能です。


あと、「setCategory」には「withOptions」が付加でき、以下のような
記述も可能です。

//AVFoundationのインスタンス
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
   
//カテゴリとオプションの設定
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
                    withOptions:AVAudioSessionCategoryOptionAllowBluetooth
                      error:nil];
 
//AVFoundation利用開始
[audioSession setActive:YES error:nil];


withOptions」は以下の種類がありますので
設定可能なカテゴリが限られていますが、必要に応じて組み合わせて使ってみてください。

//withOptionsの一覧

AVAudioSessionCategoryOptionMixWithOthers
//オーディオ再生中に別のアプリを起動した場合も中断させずに利用を可能にする。

//以下のsetCategoryのみ
//AVAudioSessionCategoryPlayAndRecord
//AVAudioSessionCategoryPlayback

AVAudioSessionCategoryOptionDuckOthers
//オーディオ再生しながら、カーナビや音声ネビゲーションアプリの利用を可能にする。

//以下のsetCategoryのみ
//AVAudioSessionCategoryPlayAndRecord
//AVAudioSessionCategoryPlayback

AVAudioSessionCategoryOptionAllowBluetooth
//Bluetooth対応機器を利用可能なデバイスとして利用可能にする。

//以下のsetCategoryのみ
//AVAudioSessionCategoryPlayAndRecord
//AVAudioSessionCategoryPlayback

AVAudioSessionCategoryOptionDefaultToSpeaker
//マイクから拾った音声がデフォルト(受話部)から出力されるのを
//スピーカー部からの出力が可能にする。

//以下のsetCategoryのみ
//AVAudioSessionCategoryPlayAndRecord

【iphoneアプリ】iOS 7で非推奨になった drawAtPoint編

2014年2月現在

本屋などに売っているObjectiv-cの本は、ほぼiOS 6以下のバージョンで
サンプルを書かれている事が多い。

そのため、iOS 7で非推奨になったプロパティなどが出て来た際
代替え方法、また代わりのメソッドなど、本にも載ってなく
リファレンスには非推奨と書かれてるだけで、詳しく説明されていない。
(詳しく調べれば、載っているかもですが...)


そんな状況なので、自分で調べたiOS 7対応を書いて行きたいと思います。
また、参考もしくは、もっと良い方法があれば教えてください。



今回は、文字の描画で使う「drawAtPoint」についてです。


以下の書き方は、iOS 6以下のバージョン時に記述していた内容です。

UIFont *font = [UIFontfontWithName:@"Verdana-Bold"size:20];

[@"iOS7では非推奨" drawAtPoint:CGPointMake(x,y) withFont:font];

しかし、iOS 7では、「drawAtPoint」の「withFont」は
非推奨となり、Xcodeでは注記対象となってしまいます。


そのため、「withAttributes」を使って、以下の内容に書き換える必要があります。

UIFont *font = [UIFontfontWithName:@"Verdana-Bold"size:20];

[@"iOS7対応" drawAtPoint:CGPointMake(x,y) withAttributes:@{
            NSFontAttributeName:font}];


また、フォントカラーも変更したい場合は以下のように書きます。

 UIFont *font = [UIFontfontWithName:@"Verdana-Bold"size:20];
UIColor *color = [UIColor redColor];

 [@"赤い文字が表示されます。" drawAtPoint:CGPointMake(x,y) withAttributes:@{
            NSFontAttributeName:font
            NSForegroundColorAttributeName:color}];


その他、変更できる項目が下記のようにありますので、
用途に合わせて使ってください。

NSString* const NSFontAttributeName;// フォント名 
NSString* const NSParagraphStyleAttributeName;// 段落の書式
NSString* const NSForegroundColorAttributeName;// 文字色
NSString* const NSBackgroundColorAttributeName;// 背景色
NSString* const NSLigatureAttributeName;// リガチャ
NSString* const NSKernAttributeName;// カーニング
NSString* const NSStrikethroughStyleAttributeName;// 取り消し線
NSString* const NSUnderlineStyleAttributeName;// 下線
NSString* const NSStrokeColorAttributeName;// 枠線の色
NSString* const NSStrokeWidthAttributeName;// 枠