2014年4月5日 星期六

iOS 開發筆記 - ALAssetsLibrary assetForURL defaultRepresentation fullResolutionImage - Terminated due to Memory Pressure

最近設計 app 時,開始把圖片存進內建得相本裡,而不使用 app sandbox 空間,然而要取出圖片時,就會碰到 Terminated due to Memory Pressure 的問題,追一下,大概是瞬間取太多張照片 :P 此為 ARC 模式。

解法:
  1. 降低瞬間取照片的數量
  2. 使用 @autoreleasepool{ } 處理記憶體管理
例如:

[self.library assetForURL:[NSURL URLWithString:@"assets-library://..."] resultBlock:^(ALAsset *asset) {
                                //NSLog(@"asset:%@",asset);
                                UIImage *image = nil;
                                @autoreleasepool {
                                    image = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
                                }
                            } failureBlock:^(NSError *error) {
                            }];


只是,這樣也沒有真的避免大量記憶體的使用 Orz 因為 [asset defaultRepresentation] fullResolutionImage] 真的吃滿大的記憶體,例如 5MB 大小的照片,處理一張照片時,記憶體會瞬間加了 30~50MB,所以瞬間處理 3~5 張時,記憶體還可能衝到 2xxMB ,直到 Terminated due to Memory Pressure。暫時想到的解法就只能透過降低處理照片的張數了。

實際例子是 app 初始化完大概 20MB 記憶體,跑上述 code 處理 3 張照片可以吃到 90MB,不曉得是不是 CGImage 的關係?改天有空再追一下。

2014年3月31日 星期一

[Linux] 架設 Proftp 與 FTP over TLS 供網頁工讀生上傳資料 @ Ubuntu 12.04

突然收到個命令,要架一檯機器給工讀生用 Orz 雖然幾乎都用 sftp 了,為了讓不熟 Unix 的網頁開發者可以輕鬆上傳資料,最後就是架一台機器,開個 ftp 讓他連進去使用。

流程:

$ sudo apt-get install nginx proftpd
$ sudo vim /etc/proftpd/proftpd.conf
Include /etc/proftpd/tls.conf

$ sudo vim /etc/proftpd/tls.conf
TLSEngine                               on
TLSLog                                  /var/log/proftpd/tls.log
TLSProtocol                             SSLv23
TLSRSACertificateFile                   /etc/ssl/certs/proftpd.crt
TLSRSACertificateKeyFile                /etc/ssl/private/proftpd.key

$ sudo openssl req -x509 -newkey rsa:1024 -keyout /etc/ssl/private/proftpd.key -out /etc/ssl/certs/proftpd.crt -nodes -days 3650

$ sudo vim /etc/proftpd/conf.d/AuthUserFile.conf
DefaultRoot ~
AuthUserFile /etc/proftpd/ftpd.passwd
RequireValidShell off

$ id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ sudo ftpasswd --file /etc/proftpd/ftpd.passwd --passwd --name webadmin --home /usr/share/nginx/www --shell=/bin/false --uid 33

$ sudo chown -R www-data:www-data /usr/share/nginx/www

$ sudo service proftpd restart

2014年3月28日 星期五

[PHP] foreach $key => $value Passing by Reference Problem

最近開發時,碰到了一個 passing by reference 的問題,追了一陣子才發現 Orz

程式碼:

<?php

$a = array( 'A', 'B', 'C' , 'D' );
print_r($a);
foreach( $a as &$v )
        $v = strtolower($v);
$v = 123123123;
print_r($a);


結果:

Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => D
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => 123123123
)


可以看到上述的最後一個 element 變成 123123123,而解法就是透過 unset 來處理:

<?php
$a = array( 'A', 'B', 'C' , 'D' );
print_r($a);
foreach( $a as &$v )
        $v = strtolower($v);
unset($v);
$v = 123123123;
print_r($a);


結果:

Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => D
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)

2014年3月27日 星期四

[Linux] MySQL 資料庫 charset 從 latin1 轉 utf8 筆記 @ Ubuntu 12.04

昨天剛順利移機([Linux] 透過 MySQL Replication 之 Master Slave 切換進行 DB server 移機 @ Ubuntu 12.04),移機後自以為沒事就收工了,結果發現 MySQL DB Server 預設的 charset 是 latin1 而非 utf8 ,接著就開始改設定檔([Linux] MySQL Server & Client characterset 設定 @ Ubuntu 12.04),以為改完沒事...才發現大條的才剛開始。

那就是昨天移機後的資料,都是以 latin1 編碼儲存進去的:

mysql> \s
...
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
...
mysql> SELECT message FROM TABLE;


會有一堆看不懂,改用 latin1 編碼就看懂了

mysql> SET NAMES latin1;
mysql> \s
...
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    latin1
Conn.  characterset:    latin1
...
mysql> SELECT message FROM TABLE;


接著就在想到底該怎樣轉 XD 因為 TABLE 的 charset 是 UTF8 編碼,不管怎樣做 convert, cast 似乎都沒成效,最後找到一些招術,幸運地真的解掉,流程:
  1. 先備份資料庫
  2. 先確認到底是哪幾筆資料有問題,用 mysqldump db_name table_name --where "id>=100 AND id <=200" > data.sql 的方式匯出
  3. 修改 data.sql 的 table 名稱、編碼定義(例如 TABLE_LATIN1、DEFAULT CHARSET=latin1),記得要把 table 改名稱,以免匯入時會 DROP 之前的資料
  4. 匯入 data.sql
  5. 建立一個新 table ,其資料表跟 TABLE_LATIN1 一樣,但 DEFAULT CHARSET=utf8,名為 TABLE_UTF8
  6. 設定 mysql 編碼為 latin1 ,並從 TABLE_LATIN1 取出資料,以 CONVERT(message USING BINARY) 存入 TABLE_UTF8 中
  7. 設定 mysql 編碼為 utf8 ,接著查證 TABLE_UTF8 是否正確,若正確的話,可以把資料從 TABLE_UTF8 更新到為本的 table 中
連續動作:

$ mysqldumo -u account -p db_name table_src_name --where 'id>=100 AND id<=200' > table_src_name.latin1.sql
$ vim table_src_name.latin1.sql
-- ...
DROP TABLE IF EXISTS `table_src_name_latin1`;
CREATE TABLE `table_src_name_latin1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
-- ...

$ mysql -u account -p -D dbname < table_src_name.latin1.sql
$ mysql -u account -p
mysql> use db_name;
mysql> CREATE TABLE `table_src_name_utf8` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
mysql> \s
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
mysql> SET NAMES latin1;
mysql> \s
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    latin1
Conn.  characterset:    latin1
mysql> INSERT INTO table_src_name_utf8 SELECT id, CONVERT(message USING BINARY) FROM table_src_name_latin1;
mysql> SET NAMES utf8;
mysql> SELECT * FROM table_src_name_utf8;
mysql> UPDATE table_src_name as d, table_src_name_utf8 as s SET d.message = s.message WHERE d.id = s.id;

[Linux] MySQL Server & Client characterset 設定 @ Ubuntu 12.04

這...太久沒設定了,記得 n 年前也都會碰到 Orz

首先先查詢現況:

mysql> status;
...
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8


接著設定:

$ ls -la /etc/mysql/
total 24
drwxr-xr-x  3 root root 4096 Mar 27 08:58 .
drwxr-xr-x 91 root root 4096 Mar 26 22:41 ..
drwxr-xr-x  2 root root 4096 Mar 27 09:03 conf.d
-rw-------  1 root root  333 Mar 25 16:00 debian.cnf
-rwxr-xr-x  1 root root 1220 Jan 22 05:48 debian-start
-rw-r--r--  1 root root 3638 Mar 27 08:56 my.cnf
$ sudo touch /etc/mysql/conf.d/charset.cnf
[client]
default-character-set=utf8

[mysqld]
character-set-server=utf8
collation-server=utf8_unicode_ci

$ sudo service mysql restart


再查詢一次:

mysql> status;
...
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8


參考資料: