property ぷろぱてぃ
@property (nonatomic,copy) NSString* name;
———————
atomic
省略時のデフォルト。synchronizedでスレッドセーフにしたgetter,setterを生成します。
nonatomic
スレッドセーフでない単純なgetter,setterを生成します。iOSではパフォーマンスの問題からほとんどの場合nonatomicにすべきです。
———————
readwrite
デフォルト。getter/setter両方を生成します。
readonly
getterのみ生成します。
———————
geter=メソッド名
getterの名前を設定する。デフォルトはプロパティ名と同じ。BOOL 型のプロパティの名前を is〜とすると分かりやすくなります。
seter=メソッド名
setterの名前を設定する。デフォルトは「setプロパティ名」。あまり使われることはありません。
———————
assign
非オブジェクト型のデフォルト。NSIntegerなど値型、C由来の型など、メモリ管理が必要ないものに使用します。オブジェクト型の場合はassignでなくweakかunsafe_unretainedが推奨されます。
strong
オブジェクト型のARC環境デフォルト。setterで代入前のものをreleaseし、新たに代入するものをretainします。非オブジェクト型には使用できません。
retain
strongと全く同じです(参考:Transitioning to ARC Release Notes)
weak
オブジェクト型の非ARC環境デフォルト。代入時にretain/releaseを行いません。メモリアクセスエラーを避けるため参照先が解放された時はnilになります。strongと同様、非オブジェクト型には使用できません。
unsafe_unretained
weakと似ていますが、releaseされてもnilになりません。assignと同じですが、こちらはオブジェクト型を対象としています。
copy
retain/releaseする点はstrongと同じですが、代入時にsetterで引数のオブジェクトをretainせずに、新たなオブジェクトとしてコピー(_value = [value copy])してからretainします。用途としてはNSStringなどmutableな型(NSMutableString)が子クラスとして存在するものについて、代入後に外部からの値の変更を防ぐためにstrongの代わりにcopyを使用します。
Webからファイルを取得して保存
URL指定でファイルを取得したい場合、従来は以下の方法で取得できたが NSURLConnectionは deprecated(非推奨) となった
//取得先のコンテンツのURLを設定 NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/test/mydata.txt"]; ]; //リクエストを作成 NSURLRequest *req = [NSURLRequest requestWithURL:url]; //レスポンスを作成 NSHTTPURLResponse *res; NSData *contents = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:nil]; // ファイルへ書き出す NSString *path = [NSString stringWithFormat:@"%@/mydata.txt", NSHomeDirectory()]; BOOL ret = [contents writeToFile:path atomically:YES];
NSURLSession dataTaskWithRequest:completionHandler に変更せよとのこと
// NSURLSession を使った方式 //NSURLSessionDataTaskは非同期タイプなので、待ち合わせを行う為に、セマホを使う // 初期値 0で作成しているので、初回は必ず、待ち状態になる。 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //リクエストオブジェクトを作成 NSURL *url = [NSURL URLWithString:@"http://uid:password@localhost/test_login_basic/test.txt"]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; /* NSURLSessionConfiguration データをアップロードおよびダウンロードするときに使用する動作およびポリシーを定義します。 データをアップロードまたはダウンロードするときは、常に設定オブジェクトを作成する必要があります。 このオブジェクトを使用して、タイムアウト値、キャッシュポリシー、接続要件、 およびNSURLSessionオブジェクトで使用する他の種類の情報を構成します。 ephemeralSessionConfiguration エフェメラルセッション構成オブジェクト キャッシュ、Cookie、または資格情報に永続ストレージを使用しないセッション構成を返します。 */ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; /* dataTaskWithRequest:completionHandler: 指定されたURL要求オブジェクトに基づいてURLの内容を取得し、完了時にハンドラを呼び出すタスクを作成します。 このタスクは、応答とデータ配信のためにメソッドを委譲するための呼び出しをバイパスし、 代わりに結果のNSData、NSURLResponse、およびNSErrorオブジェクトを補完ハンドラ内に提供します。 ただし、認証の問題を処理する代理メソッドは引き続き呼び出されます。 引数 completionHandler ロード要求が完了したときに呼び出す完了ハンドラ。 このハンドラはデリゲートキューで実行されます。 nilを渡すと、タスクが完了するとセッションデリゲートメソッドだけが呼び出され、 このメソッドはdataTaskWithRequest:メソッドと同等になります。 */ NSURLSessionDataTask *task = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"did finish download.\n%@", response.URL); if (error) { NSLog(@"%@", error); dispatch_semaphore_signal(semaphore); return; } NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if (httpResponse.statusCode != 200) { dispatch_semaphore_signal(semaphore); return; } NSString *path = [NSString stringWithFormat:@"%@/mydata.txt", NSHomeDirectory()]; BOOL ret = [data writeToFile:path atomically:YES]; if ( ret == YES ) { NSLog(@"ファイルがダウンロードできました"); } else { NSLog(@"ダウンロードに失敗しました"); } /*セマホを+1する*/ dispatch_semaphore_signal(semaphore); }]; /*タスクが中断している場合は、タスクを再開します。*/ [task resume]; /* #define DISPATCH_TIME_FOREVER (~0ull) セマホが1になるまで待ち合わせをする。永遠に。 */ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"compliate");
配列 いろいろ
NSArrayからイテレータ的に値を取得
NSArray* bars = arrayWithObjects:bar1,bar2, nil]; NSEnumerator* eratorBar=[ bars objectEnumerator]; NSDictionary* aBar; while (aBar = [eratorBar nextObject]) { NSLog(@"%@", [aBar objectForKey:@"key1" ]); NSLog(@"%@", [aBar objectForKey:@"key2" ]); }
参考
http://libro.tuyano.com/index3?id=560003&page=6
http://libro.tuyano.com/index3?id=560003&page=6
segueを使わないで画面遷移
view1からview2に遷移する場合
ViewController1.m
- (IBAction)btnPage2:(UIButton *)sender { UIStoryboard* myStoryboard = self.storyboard; ViewController2* viewController2 = [myStoryboard instantiateViewControllerWithIdentifier:@"view2"]; viewController2.dataString = @"aaa"; [self presentViewController:viewController2 animated:YES completion:nil]; }
view2からの戻り遷移
ViewController2.m
- (IBAction)btnBack:(UIButton *)sender { [self dismissViewControllerAnimated:YES completion:nil]; }
ポイント
ViewControllerのIDは事前に設定しておく必要あり。
ボタンのクリックイベントとメソッドの紐付けは、control+ドラッグで行なっている。
遷移したいタイミングで、遷移が可能なので、segue を使うより感覚的に、わかりやすい。
思ったよりも簡単だった。
UIViewController のライフサイクルについて
UIViewControllerのライフサイクル - Qiita
にすばらしい説明があった
viewDidUnload とかは、以前はあったようが、途中で消滅している
viewDidUnloadがdeprecatedになった理由を考察 | Cyber Passion for iOS
参考
iOS のイベント駆動をライフサイクルイベントとユーザアクションイベントにわけて理解するhttp://glassonion.hatenablog.com/entry/20120405/1333611664
Unwind Segueによる画面遷移
戻り遷移の際に、判定を加えたい。
ネットのサンプルを見ると canPerformUnwindSegueAction を使って判定すれば良いように記述されていたが、試して見ると、例外が発生してしまう。
代わりに shouldPerformSegueWithIdentifier でならできた
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ // NOを返却すると、戻り遷移はしない return YES; }
参考
[Swift]初心者向け!Segueを使った画面遷移方法http://yuu.1000quu.com/how_to_use_segue
[Swift]コードで画面遷移を行う3つの方法http://yuu.1000quu.com/screen_transition_in_swift
UIDocumentInteractionController が iPadで有効にならない
Deployment device が iPhoneだと正常に起動するが、
Deployment device が iPadだと連携先のメニューが表示されない。
なんで?
iPhoneの場合は、中央下に表示されるが、iPadの場合は、座標を指定しないとダメみたい。
トリガーのボタンの右下の座標を基準に、選択メニューを表示するようにしてみた。
- (IBAction)btnOpen:(UIButton *)sender { [self fileOpen:@"sample.pdf" ui:sender]; } -(void)fileOpen:(NSString*)fileName ui:(UIButton*)ui { NSURL *url = [NSURL fileURLWithPath:fileName]; CGRect rect = CGRectMake(ui.frame.origin.x + ui.frame.size.width ,ui.frame.origin.y + ui.frame.size.height,0,0); isValid =[_docInteractionController presentOpenInMenuFromRect:rect inView:self.view animated:YES]; }
上記のように実装しても、iPhoneでは相変わらず、下中央に開く
参考
ios - UIDocumentInteractionController not appearing on iPad but working on iPhone - Stack Overflow