2013年9月27日金曜日

Mac miniのHDD交換方法

Mac mini(2011)のHDDに交代保留セクターが増え続け、さらに全体にアクセス速度が遅くなってきているので、完全にだめになる前に交換することにした。


基本的には下記サイト↓
http://henjinkutsu.com/text/pc/macmini2011_upgrade/
を参考にしたが、いくつか間違いがあるので補足しようと思う。


まず、交換前にTimeMachineで内容を外部HDDに全バックアップしておくこと。
BOOTCAMP領域がある場合はさらに、WincloneもしくはWindows上のバックアップツールを使ってバックアップしておく。


交換に必要なものはトルクスドライバT5/T5.5/T6/T8。T5.5がないときはペンチ。それに非常に細い(薄い)マイナスドライバ。多分にほこりも溜まっていると思うので、掃除機とかほこり取りは適当に。


外すねじは、まずは以下の通り。ねじはすべてトルクスねじ。赤線はT8、白はT6だったと思う、青はT5.5。ねじを外す前にメモリは外しておく(外さなくてもHDD交換は出来ると思うけど、念のため)。金属部分に触れて、静電気防止を忘れずに。
青の部分のねじはT5.5と思われ、私の持っているトルクスビットには存在しなかった。しかし、ここは緩いねじなので、ドライバがなければペンチでつまんで外すことが出来る(というか、そうした)。


白線T5の内左2本は2重のねじで、上側=ファンを留めているのがT5(上の写真)、ファンを外した下にあるのがT8で、それを外すと左側の黒のカバーが外れる。

これで冷却ファンが外れるようになるが、電源線のコネクタも抜かなければならない。
このコネクタは基本的には上からはめるだけだが、抜くときは隙間に非常に細いマイナスドライバを入れてゆっくりすき間を広げていく。

その後上の金属網プレートを横によける。基板とは極小コネクタで接続されているので、外さないようにする(外しても良いが、はめるのはちょっと難しいので)。
次に左側の黒カバーを外す。ちょっと引っかかりがあるので揺らしながら右方向へ抜く。



HDDは黒カバーの下、この位置でコネクタで基盤につながっているので、上に引き抜く。
HDDは手前上方向に引き出すようにする。


外したHDDがこれ。左上に見えているのが、外したコネクタ。

HDDは、横側がT8ねじで留められているので外す。

また、HDD全体に黒いシートがシールでくっついているので、丁寧にはがす。このときにも薄いマイナスドライバがあると便利。


後は、元通りに戻していくだけ。
コネクタ類をちゃんとはめることを忘れずに。
私はメモリが半分しか認識されてなくて再度開く羽目になったので。

上の金属プレートのT8ねじは、このようにちょっと浮いたような感じで閉まるので注意。

くだんのHPではHDD(SSD)の増設を目指しているようで、交換だけには不要な部分のねじなども外すように指示している。それをしようとするとT5.5ドライバが絶対必須。


新HDDへの内容リカバリは2段階で行う。
(1)インターネットリカバリーでOSを戻す。
電源ON時に「command+option+R」を押しっぱなしにして起動する。
ただし、USB-Apple純正キーボードで行うこと。
(Windowsキーでは配置が違いうまく行かない。)
このとき、下記以外のHDDや機器は一切繋がないこと。
 (USB)キーボード
 (Bluetooth)マウス
 有線LAN
 モニタ

(2)TimeMachineで復元
Command+Rで起動してTimeMachineから復元する。
新HDDの容量が旧と異なっていても問題ない(もちろん、容量的に入りきる必要はある)。
Macはこれで完全復旧する。すごい!

BOOTCAMPがある場合は、Wincloneなどで戻す。

HDDの内容を戻すのは簡単だけど、HDDの交換自体は結構手間がかかるのがMac mini2011の欠点かも。



 そうそう、外したHDDを予備に使うとか、そこから内容をコピーするとかいう場合にはSATA 2.5'のHDDケースがあると便利、と書いておこう。うちでもWindows側の設定戻しに重宝したので。
Amazonなら800円くらい。



使ったHDD


使ったドライバーセット(ただし、T5.5はない)




2013年9月18日水曜日

Objective-Cの勉強(10):Class型



Class型



クラス変数を「インスタンス化した」時、そのオブジェクトの中には「自分自身のクラス定義内容」も入っている。これを「クラスオブジェクト」という。実はこれこそがNSObjectクラスの主な機能である。
これはClass型で定義され、変数にも代入できる。代入するメソッドはclassである。


万が一クラスオブジェクトが存在しない時は「Nil」という値が返ってくる。ここではNULLは使わんようだ。



定義内容そのものを動的に取得可能というわけだ。しかも、その定義内容を元にインスタンスを作成することも出来る。型(定義)そのものを変数に代入し、その変数に代入された型で変数を宣言できるということだ。
うぉっ、ややこしい。でもなんかうまく使えば強力そう。

@interface Test : NSObject
+ (void)Write;  // クラスメソッド
- (id)init;     // インスタンスメソッド
@end
@inprementation Test
    省略
@end
int main()
{
    Class testClass = [Test class]; // Class型変数testClassを宣言し、Testというクラスのクラス情報を代入する
       // testClassはクラス宣言に相当する
    [testClass Write];         // testClass->Write();相当 Writeがクラスメソッド(+)だから呼び出せる
    [[testClass new] ObjFree]; // testClassの保持するクラス型のオブジェクトを作成→即解放している
    [testClass ObjFree];       // クラスオブジェクトを解放
    return(0);
} 
 

2013年9月11日水曜日

Objective-C勉強(9);メンバーの公開範囲



メンバーの公開範囲



通常、クラスメンバー変数はそのメソッドによってのみアクセスされるべきである。
が、メソッドの呼び出しはCの関数呼び出しに比べ(出来ることが多い分)遅いので、
高速性を求められるプログラムではメンバー変数に直アクセスアクセスする必要があるかもしれない。


しかし、全メンバーを公開してしまうと、いじられたくない部分までいじられる可能性がある(特に派生クラスを作る時)ので、公開範囲を限定できる。


@public 全公開(外部、このクラス内、子クラス内)
@private このクラス内のみ公開
@protected このクラスおよび子クラス内のみ公開;デフォルト


これを記述した後のメンバー変数は全てその公開範囲となる。クラス定義内で何回、どの順序で書いても良い。
クラスの属性値は@publicに、内部変数は@privateまたは@protectedにするといいのだろう。
C言語で言うなら、グローバル変数、ファイル内static変数、auto変数と考えるとわかりやすい。

Apple純正のObjective-C解説

によると
@publicの利用は避けるべき

と書かれている。
デバッグ時に内容読むのには使えると思うけどね(デバッグ中だけ@publicにしておく)。


ついでに書くと、クラスをidで受けてしまうとメンバー変数がコンパイル時には不定でエラーになるので、「クラス名 *」で定義する必要がある。
@interface A : NSObject
{
@public
    int a;
@protected
    int b;
@private
    int c;
}
- (id)initWithA:(int)a arg2:(int)b arg3:(int)c;
- (void)WriteA;
@end

@interface B : A
// 変数がないので{}は省略
- (void)WriteB;
@end

@implementation A
- (id)initWithA:(int)a arg2:(int)b arg3:(int)c
{
    self->a = a;  // @publicメンバーへの代入はポインタを経由して行う
    self->b = b;
    self->c = c;
    return(self);
}
- (void)WriteA
{
    printf("[A Write a=%d, b=%d, c=%d]\n", a , b , c);
}
@end

@implementation B
- (void)WriteB
{
    printf("[B Write a=%d, b=%d]\n", a , b); // cにはアクセスできない
}
@end

int main()
{
    B * objb = [[B new] initWithA:1000 arg2:100 arg3:10];
    printf("[main() a=%d]\n" , objb->a); // @publicなのでメンバー変数に直接アクセスできる
    objb->a=200; // 当然代入も出来る
    [objb WriteB];
    [objb WriteA];
    [objb ObjFree];
    return(0);
}
このあたりはCで書いてた構造体を持つライブラリを移植していくと理解が深まるのであろう。

Objective-C V2.0で導入されたプロパティを使うと自動的にアクセスメソッドを生成させることが出来るので、この公開範囲をいじるというのは「高速化を除き」今後余り行わない方が良いのかもしれない。


世間に公開するようなライブラリを作るならいざ知らず、個人の開発においてはほぼ無用であろう。
私は一度も使ったことがない。

2013年9月5日木曜日

Objective-Cの勉強(8):id型よりクラス名 *の方が安全



id型よりクラス名 *の方が安全



クラスの型としてはid型が汎用的で使いやすいが、逆に言えば型(クラス)が特定出来ないので、
持っていないはずのメソッドを呼び出してしまったりする可能性がある。

それを動的に調べる方法もあるのだが、コンパイラレベルでもある程度チェックできる。
素直に元のクラス名のアドレス型で宣言すればよいだけである。
これはコンパイルレベルのチェックを強化させるだけなので、実行時には全く影響を与えない。

@interface A : NSObject
- (void) Write;
@end
@implementation A
- (void) Write
{
    printf("Write\n");
}
@end
int main()
{
    id obj1 = [A new];      // クラスAにはWriteというメソッドが存在するが、
    id obj2 = [NSObject new]; // 親クラスであるNSObjectにはない(場合)

    [obj1 Write];
    [obj2 Write];   // 実行時にエラーとなる
    [obj1 ObjFree]
    [obj2 ObjFree]
    return(0);
}
↓これを明示的なクラス名で記述する。
int main()
{
    A * obja = [A new]; // idは元々ポインタを示す型なので、クラス名で明示する時は"*"が必須
    [obja Write];       // もしクラスAがWriteメソッドを持たない場合は、コンパイル時にエラーになる
    [obja ObjFree];
    return(0);
}
この場合は呼び出す元となるインスタンスが固定されているので、メソッドの存在があらかじめ解るが、Objective-Cでは逆に、メソッド名自体=メッセージを固定して呼び出し対象とするインスタンスを変更していく;送るメッセージは同じだが、それを解釈するオブジェクトが違う、という記述をよく行う。その場合はこの方法は使えない。

その「動的なメソッドの存在チェック方法」については後述。