Tag Archives: NSString

iOSアプリ開発:deprecated対応メモ:NSString

0
Filed under iOS SDK, トラブルシューティング
Tagged as ,

使い勝手がよいオープンソースライブラリでもメンテナンスがされていないと、使われているメソッドが新しいiOS SDKでdeprecated(非推奨)になってしまい、警告が出ることがあります。
昨今は開発している人も多いのでググるとすぐに見つかるのですが、引数が増えていたりして対応がわかりにくいことがあります。
自分でぱっと見で分かりやすいように、メモを残していきたいと思います。

【NSString】 – sizeWithFont:

Warning: ‘sizeWithFont:’ is deprecated: first deprecated in iOS 7.0 – Use -sizeWithAttributes:

・公式リファレンス → sizeWithAttributes: – NSString UIKit Additions Reference

// 素材.
NSString* str = @"hogehoge";
UIFont* myFont = [UIFont systemFontOfSize:14];
 
// OLD.
CGSize size = [str sizeWithFont:myFont];
 
// NEW.
NSDictionary* dicFontAttr = @{ NSFontAttributeName:myFont };
CGSize size = [str sizeWithAttributes:dicFontAttr];

【NSString】 – drawAtPoint:withFont:

Warning: ‘drawAtPoint:withFont:’ is deprecated: first deprecated in iOS 7.0 – Use -drawAtPoint:withAttributes:

・公式リファレンス → drawAtPoint:withAttributes: – NSString UIKit Additions Reference

// 素材.
NSString* str = @"hogehoge";
UIFont* myFont = [UIFont systemFontOfSize:14];
 
// OLD.
[str drawAtPoint:p withFont:myFont];
 
// NEW.
NSDictionary* dicFontAttr = @{
  NSFontAttributeName:myFont,
  NSForegroundColorAttributeName:textColor }; // テキストの色はここで指定.
[str drawAtPoint:p withAttributes:dicFontAttr];

【NSString】 – drawInRect:withFont:lineBreakMode:alignment:

Warning: ‘drawInRect:withFont:lineBreakMode:alignment:’ is deprecated: first deprecated in iOS 7.0 – Use -drawInRect:withAttributes:

// 素材.
NSString* str = @"hogehoge";
UIFont* myFont = [UIFont systemFontOfSize:14];
CGRect rectArea = CGRectMake(0, 0, 320, 50);
 
// OLD.
[str drawInRect:rectArea
       withFont:myFont
  lineBreakMode:NSLineBreakByWordWrapping
      alignment:NSTextAlignmentCenter];
 
// NEW.
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineBreakMode = NSLineBreakByWordWrapping;
style.alignment = NSTextAlignmentCenter;
NSDictionary *attributes = @{
  NSForegroundColorAttributeName:textColor,
  NSFontAttributeName:myFont,
  NSParagraphStyleAttributeName:style
};
[str drawInRect:rectArea withAttributes:attributes];

[AD]↓評判がいいので私も買いました!

基礎からわかる Swift

著者/訳者:坂本 俊之

出版社:シーアンドアール研究所( 2014-11-20 )

定価:

Amazon価格:¥ 2,484

単行本(ソフトカバー) ( 248 ページ )

ISBN-10 : 4863541589

ISBN-13 : 9784863541580


[AD]↓kindle版を買って読んでいます!

Stack Overflowを起点に勉強してみる

0
Filed under iOS SDK, ウェブサービス
Tagged as , , ,

Stack Overflowというサイトは、様々なプログラムに関するQ&Aサイトで、iOS SDK関係もかなりピンポイントの質問に対して答えられていたりして、なかなか有益な情報が集まっています。Appleのオフィシャルフォーラムよりこっちのほうがgoogleでひっかかるし、調べ易いですね。
Matthieu Ricard - World Economic Forum Annual Meeting Davos 2009photo © 2009 World Economic Forum | more info (via: Wylio)
そんなStack Overflow、全く自分に関係ない問題でも、ちょっと目を通すと何かしら勉強になるかも、と思って、気分転換にいくつかの記事を見てみました。

NSLogで数値がいつも0と出力される

この問題は割と簡単で、値がCFFloatなのに、printf変換指定子が%dと整数指定しているから、というのが普通の回答
しかし、このスレッドで有益なのは、hoha氏が回答している「簡単にCGRectの内容を文字列出力できるよ」という回答です。

1
NSLog(@"currFrame dimensions: %@", NSStringFromCGRect(currFrame));

NSStringFromCGRect、これは確かに便利!

NSString変換便利メソッド群

ということで、ちょっとリファレンスを調べてみたら、UIKit/UIKit.h には、まだまだ他にも便利なNSString変換メソッドがありました。
よく使いそうなのは次の3つかな。

1
2
3
NSString* NSStringFromCGPoint( CGPoint point ); 
NSString* NSStringFromCGRect( CGRect rect );
NSString* NSStringFromCGSize( CGSize size );

さらに興味深いことに、次のメソッドで反対の機能(文字列→オブジェクト)を実現出来るのです!

1
2
3
CGPoint CGPointFromString( NSString *string ); 
CGRect CGRectFromString( NSString *string );
CGSize CGSizeFromString( NSString *string );

直接値を代入するより実行速度が遅いとは思いますが、何かの時には便利そう!
例えば、こんな感じで文字列からオブジェクトを生成できます。

1
CGPoint point = CGPointFromString( @"{3.0,2.5}" );

引数にはカンマ区切りの2つの数値を中括弧でくくった文字列。正しく変換出来ない文字列が渡された場合には、CGPointZeroが返るらしい。
残りの二つはこんな感じ。

1
2
CGRect rect = CGRectFromString( @"{{3,2},{4,5}}" );
CGSize size = CGSizeFromString( @"{3.0,2.5}" );

それぞれ、変換エラー時には、CGRectZero、CGSizeZeroが返ります。


[AD]

↓今一番気になるiOS開発関係の本。見出しより→「高レベルで拡張的なアプリを半自動的に作る」!??

iOS開発におけるパターンによるオートマティズム

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2011-02-09 )

定価:

Amazon価格:¥ 2,940

単行本 ( 208 ページ )

ISBN-10 : 4861007348

ISBN-13 : 9784861007347


↓カメラアプリを開発するならこの本!という定番になるかな?自分も時間があれば乱造してみたい!!

iPhoneデジカメプログラミング

著者/訳者:細谷 日出海

出版社:ソフトバンククリエイティブ( 2011-03-18 )

定価:

Amazon価格:¥ 3,024

大型本 ( 344 ページ )

ISBN-10 : 4797362324

ISBN-13 : 9784797362329


↓iOS開発本ってたまにこういうオシャレ装丁系が出てくる。プラットフォームの魅力がそうさせるのか?

ジオモバイルプログラミング—iPhone&Androidで位置情報アプリを作ろう—

著者/訳者:郷田まり子 宅間俊志 近藤昭雄

出版社:ワークスコーポレーション( 2011-01-27 )

定価:

Amazon価格:¥ 3,780

単行本 ( 356 ページ )

ISBN-10 : 4862670989

ISBN-13 : 9784862670984


Objective-Cの既存のクラスを拡張する仕組み

2
Filed under iPhone, Objective-C, プログラミング言語
Tagged as , , , , , ,

Objective-Cには「カテゴリ」という機能があり、それについて調べたときのメモをまとめました。

その名は「カテゴリ」

ネットに転がっているソースを見ていて、それまで見たことなかった書き方があったときにはそれをどうやって調べたらいいのか、なかなか手こずります。その書き方そのものの名を知らないからです。
今回の例で言うと「カテゴリ」という機能のことで、下記のような感じで書かれていたら、それはカテゴリ機能を使っているのです。

1
@inteface NSString (HogeHoge)

このカテゴリ機能を活用すると、既存のクラスをちょっと機能拡張したい時に無駄なクラスを作る必要がなくなります。
例えば、文字列を扱うクラス NSString をに機能を追加したいことはよくあるのですが、NSStringの中身に応じたハッシュ値(MD5)を出力できるようなメソッドを追加する、という例に説明してみます。
MD5の機能実装の参考にしたのはこちらのサイト。関数の中身は全く同じです。

ざっくりしたカテゴリの書き方と使い方

まず、カテゴリ定義の書き方。
NSStringにMD5の機能を追加する場合、ファイル名は、NSString+MD5.h, NSString+MD5.m とするのがマナーのようです。
また、後述するソースを見ると分かるのですが、定義部は @inteface NSString (MD5)、実装部は @implementation NSString (MD5) という感じにして、あとは通常のクラス定義と同じように書きます。
次に使い方ですが、#import “NSString+MD5.h” として一緒にビルドすれば、そのソース内でNSStringインスタンスは全てMD5カテゴリの機能を持つことが出来ますので、下記のようなコードでMD5値を出力させることが出来ます。

1
2
NSString* strTest = @"テスト文字列";
NSLog( @"original[%@], MD5[%@]", strTest, [strTest MD5String] );

NSString+MD5 コード全容

1
2
3
4
5
6
7
//  NSString+MD5.h
 
#import <Foundation/Foundation.h>
 
@interface NSString (MD5)
- (NSString*) MD5String;
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//  NSString+MD5.m
 
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h> // for CC_MD5
 
@implementation NSString (MD5)
- (NSString *) MD5String
{
  const char *cStr = [self UTF8String];
  unsigned char result[CC_MD5_DIGEST_LENGTH];
  CC_MD5( cStr, strlen(cStr), result );
  return [NSString stringWithFormat:
    @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7],
    result[8], result[9], result[10], result[11],
    result[12], result[13], result[14], result[15]
    ];  
}
@end

iOS SDKのMD5関数についての説明

おまけとして、上記のソースの内容を説明します。
MD5への変換関数 CC_MD5はiOS SDKにC言語ライブラリが用意されています。(リファレンスはこちら

CC_MD5は、次のように定義されています。

1
2
extern unsigned char*
CC_MD5(const void *data, CC_LONG len, unsigned char *md);

data が元になるデータのポインタ。
len がdataの長さ。
md がMD5計算の結果を格納する出力用バッファへのポインタで、CC_MD5_DIGEST_LENGTHの長さが必要なので、予め用意しておきます。本当はCC_MD5_DIGEST_LENGTHの長さに合わせて、出力部分を対応できるよう書いておく必要がありますが、CC_MD5_DIGEST_LENGTHは、そうそう16から変わることはないので、出力部分を固定で16要素並べてstringWithFormatで出力させています。

クラスの機能分割、という視点

カテゴリについての詳しい説明は、「Dynamic Objective-C」という書籍にも3ページに渡って説明されているのですが、こちらでの視点はチョット違う。

Dynamic Objective-C

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2009-03-27 )

定価:

Amazon価格:¥ 1,600

単行本(ソフトカバー) ( 456 ページ )

ISBN-10 : 4861006414

ISBN-13 : 9784861006418


そのセクション名は「カテゴリ ―動的なメソッドの追加によるクラスの拡張」となっていながらも、最初の段落の説明は次にように書かれている。

Objective-Cには、カテゴリと呼ばれる機能がある。クラスが持つメソッドを、名前の通りカテゴリごとに分類するための機能だ。これを使うことで、大きなクラスでもコーディングしやすいように分割することができる。

そもそもカテゴリとは、クラス実装を分割するための仕組み、だというのだ。
なるほど、そう考えるとカテゴリが「カテゴリ」という名前の由来もわかるし、ウェブに転がるサンプルのファイル名がHOGEHOGE-FOO.hとかハイフン繋ぎになっているモノがあるのも理解できる。
MVCモデルでクラスを分けても大きくなってしまうクラスはあるし、その場合にはカテゴリを使った機能分割も視野に入れていいかもしれない。
その他にもObjective-Cの深いところをじっくり説明してくれている「Dynamic Objective-C」はおすすめ書籍です!

カテゴリで出来ないこと

後から知ったのですが、カテゴリ機能で「クラスのインスタンス変数の追加」は出来ないようですね。
これ、結構重要なポイントだと思います。

参考サイト:『kuro’s blog : Objective-C:カテゴリで「できること」と「できないこと」』


[AD]

↓「CHAPTER09 カテゴリ」とカテゴリについて章を割いて説明されているようです!

詳解 Objective-C 2.0 改訂版

著者/訳者:荻原 剛志

出版社:ソフトバンククリエイティブ( 2010-12-17 )

定価:

大型本 ( 608 ページ )

ISBN-10 : 4797361786

ISBN-13 : 9784797361780


↓昨年8月に亡くなった今敏が1985年〜1986年に連載していたマンガ!面白そう!

OPUS(オーパス)上(リュウコミックス) [コミック]

著者/訳者:今 敏

出版社:徳間書店( 2010-12-13 )

定価:

コミック ( 193 ページ )

ISBN-10 : 4199502211

ISBN-13 : 9784199502217


↓PS3もXbox360も持っていないけど、これは面白そう!

キャサリン 特典 サントラCD付き

キャサリン 特典 サントラCD付き

定価:¥ 7,538

Amazon価格:¥ 8,750

カテゴリ:Video Game

発売日:2011-02-17


Objective-CでNSStringプロパティ実装

0
Filed under Objective-C, プログラミング言語
Tagged as , , , , ,

Objective-Cをなんとなく使い続けていたのですが、分かってるようであまり分かっていなかったのがプロパティ
retain/release/autorelease周りとの絡みもあってなんとなくやり過ごしていたのですが、ちょっと切羽詰ってきたので仕切りなおして勉強してみました。

NSStringを持つクラスでテスト

いろいろ調べた結果、とりあえず、下記のようなクラスStringContainerを定義しておけば問題なく使えるっぽいです。(問題見つけたら教えてください!)
まずは、定義ファイル。内部にNSString*のインスタンス変数を二つと、そのプロパティ宣言を行っています。
重要なポリシーは、propertyは内部でコピーする、ということ。下記のページを参考にしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
//  StringContainer.h
#import <Foundation/Foundation.h>
 
@interface StringContainer : NSObject {
	NSString*	str0;
	NSString*	str1;
}
 
// コピーするので、渡すものはautoreleaseしておいてください.
@property (nonatomic,copy) NSString* str0;
@property (nonatomic,copy) NSString* str1;
 
@end

次に実装コードです。プロパティ設定のためのsynthesizeと、デストラクタを定義しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//  StringContainer.m
#import "StringContainer.h"
 
@implementation StringContainer
 
@synthesize str0, str1;
 
-(void) dealloc{
	[super dealloc];
 
	[str0 release];
	[str1 release];
}
 
@end

そして、テストコード。str0とstr1では別の与え方をしてみました。

1
2
3
4
5
6
7
8
// Test.m
// 確保.
StringContainer* scTest;
scTest = [[StringContainer alloc] init];
 
// 各パラメータを設定.
scTest.str0	= [NSString stringWithFormat:@"Default 0[%d]",0];
scTest.str1	= [[[NSString alloc] initWithFormat:@"Changed 1[%d]",11] autorelease];

str0に渡す文字列は、stringWithFormatはクラスメソッドで生成。なので、そこで生成されたオブジェクトはそちらでAutoRelease Poolに入っているようなので、特にrelease/autoreleaseを行う必要はありません。むしろ、それをやると、retain countが0になったときに、二重にreleaseが呼ばれるので、問題となります。
str1に渡す文字列は、alloc, initで生成したもの。ここで生成しているので、ここでautoreleaseしています。代入後に即releaseしても問題有りませんが、ここでrelease/autoreleaseのどちらかを行っていないと、そのメモリは破棄されないので、リークしてしまいます。

これでOKのハズ!

一応、Instrumentsツールを使ってリークを調べたりもしたので、これで大丈夫だと思うのですが、認識に問題があったら誰か教えて欲しいです!!!
たったこれだけのことを自信持ってかけるようになるのに半日かかりました!
AutoRelease Poolというものの存在、クラスメソッドで定義したものがそちらで勝手にautoreleaseされているっぽい、ということ、それらをググって知ったので理解できたのですが、そうでなかったらなかなか辿り着けないのです。
ちなみに、NSArrayも同様な書き方でプロパティ実装できるはずです。


[AD]
↓この本、買いました!ウェブで連載されていたコラムの総集編とiPhone Hackコラムの書き下ろし。読み物として書かれているので、飽きずに読めてる!Objective-Cの実装部分まで踏み込んでいるので、ダイナミック言語としての面白さを知ることができるし、後半ではデザインパターンの実装の話にもなる。

Dynamic Objective-C

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2009-03-27 )

定価:

Amazon価格:¥ 1,600

単行本(ソフトカバー) ( 456 ページ )

ISBN-10 : 4861006414

ISBN-13 : 9784861006418



↓これも店頭で見ていい!と思って買いました。iPhoneプログラムのコネタ集なんだけど、一つ一つが過不足無く説明とコードが書かれていて、本当にすばらしい!版型もちょっと小さいので、鞄に入れて移動中に気になるところをちょっとずつ読むスタイルもオススメ。

iPhoneSDK開発のレシピ

著者/訳者:高山 恭介 広部 一弥 松浦 晃洋

出版社:秀和システム( 2010-03-23 )

定価:

Amazon価格:¥ 2,592

単行本 ( 319 ページ )

ISBN-10 : 4798025798

ISBN-13 : 9784798025797