1. String to java.sql.date

SimpleDateFormat ts= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Long time = ts.parse("2007-05-16 13:12:18").getTime();

java.sql.Date date = new java.sql.Date(time);

 
SimpleDateFormat으로 부터 형식에 맞는 Date String을 parse한후 long 값 생성.
long값을 통해 java.sql.Date 객체를 생성한다.

2. java.sql.date.to String

SimpleDateFormat ts= new SimpleDateFormat("yyyyMMddHHmmss");

return ts.format(date);

 
 SimpleDateFormat Object의 format() method를 통해 String을 쉽게 Generate할 수 있다. 

SimpleDateFormat Class Reference Link

Abandoned Memory ?

흔히 얘기하는 Leaked Memory 는 reference가 존재 하지 않는 잃어버린 Memory를 이야기한다. 

그럼 Abandoned Memory는 무엇일까?

Abandoned Memory는 Reference가 존재하지만 사용하지 않는 Memory 이다.

Abandoned Memory
는 Profiler가 찾을 수 없기 때문에, Debugging하기가 매우 어렵다.
허나, Instrument 의 Heap Shot기능을 이용하면,
비교적 쉽게 Debugging이 가능하다. Abandoned Memory를 찾아 낼수 있다.

Heapshot의 기능? 

Heapshot의 기능은 Heapshot간의 Memory Allocation Diff 정보를 제공한다는것이다.

HeapShot#0 -> Do some task -> HeapShot#1

이런식으로 흘러 갔을때, HeapShot#0와 HeapShot#1의 Memory allocation Diff가 0 bytes가 되는것이 이상적이라 할수 있겠다.

현실에선, Cache등의 이유로 Diff가 0가 되는일은 거의 없겠다.

허나 HeapShot이 Diff를 제공하기에 Task 후에 살아 남은 Memory Block들을 한눈에 볼수 있고,
내가 의도지하지 않은 Memory Block을 비교적 쉽게 찾아 낼 수 있다.

HeapShot 예제


위의 Sample Program은 2 Button이 존재하며, Memory Leak을 유발하는 Button 하나와 아무것도 하지 않느 버튼 하나가 존재한다.

-(IBAction) pressLeak:(id)aSender {

    [[NSArray alloc] initWithObjects:@"abcdef",@"abcdef",@"abcdef",@"abcdef", nil];

}


Leak Button을 Touch 하면 아무의미 없이 NSArray Object하나를 만든다. 


Profile 모드로 앱을 실행시키고, Instrument Template은 "Allocation"을 선택한다.

좌측 메뉴의 MarkHeap을 눌러 Heap shot을 찍을 수 있다.

아래 그림은 Heapshot을 찍은후의 Heapshot List이다.


Heap Growth Column이 Heapshot을 찍었을 당시의 이전 HeapShot과의 Memory Diff라고 보면 된다.
Memory Leak을 보여주는것이 아니라, Memory Allocation Diff를 보여주는것이기때문에,
Heapshot에 기록되는 모든 Memory가 Leak 혹은 Abandoned 되었다고 판별할 수 없다.

필자는 Heapshot4와 Heapshot8을 찍기 직전에 "Leak" button을 Touch 했다.

 
Heapshot8을 펼쳐 보면 예상과의 달리 Object들이 많이 생성되었다.
아마 Touch Handling을 위해 Framework단에서 생성하는 Object들일것이다.

위의 Test Code를 보면 NSArray를 만들었기에,  유일한 NSArray Object의 생성주기를 보자.(Instrument 우측 View에 나타난다.)


우측에 보면, Object가 만들어진 Stack Trace가 노출되고, Framework 코드가 아닌, 내가 작성한 코드는 Bold로 Highlight된다.
해당 부분을 Double Click 하면 코드도 볼수 있다.


생각보다 Smart한 방법은 아니고, 사람에 의존적인 방식이다.
허나 Diff를 제공하여, 살아 남은 Object 를 추적할 수 있기에, 매우 유용하다.

Memory 문제에 자유로운 개발자는 아마 없을터,
Leaked Memory가 아니라, Abandoned Memory 를 찾아 내는데는  꽤나 유용한 Tip이라고 생각한다.
 

A.Java

package a;

public class  A extends B {}

 
B.Java

package b;

 abstract class B {}

 
위와 같은 Code는 아래와 같은 Compile Error가 발생합니다.

B cannot be resolved as a type


A 에서 extneds 하려는 B abstract class를 못찾는것인데,
이유인 즉은 class B 가 "no modifier"로 선언 되어 있어서 그런것이지죠.
앞에 "public" keyword를 추가해주면 error는 말끔히 사라집니다.

default 가 protected 같은 녀석이 되어 있어서, 그러려니 했었습니다만,
혹시나 해서 문서를 찾아 봤습니다.

java 에서 access control 은 아래의 4종류가 있습니다..

* public
* private
* protected
* no modifier


여기서 중요한게 no modifier가 따로 있다는 것입니다.
저는 default behavior가 protected라고 추측했었는데, 그게 아니었던것이지요.

C Language를 오래했던 제가, Java에 대해 공부가 부족했던 오해 인가 봅니다.
Scope등의 자세한 내용은 "http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html" 여기서 참조 하시기 바랍니다.

참고로, protected 는 class 에는 붙힐 수 없고, memeber variable에만 적용됩니다. ㅎ



 
 
http://developers.facebook.com/docs/guides/mobile/#android

FaceBook사에서 Guide를 했는데도 불구하고,

07-29 10:11:50.140: DEBUG/Facebook-authorize(11292): Login failed: invalid_key


 위와 같은 error가 발생하며, Login Page로 가지 않는 문제가 있었다. 
 
이래저래 서치를 해본 결과
Android Hash Key를 생성하는데서 문제가 있었다. 
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore 
| openssl sha1 -binary
| openssl base64

http://developer.android.com/guide/publishing/app-signing.html#debugmode

Android 개발자 사이트를 보면, debugmode에서의 app-sigining에 대한 내용이 있다.

Eclipse에서 applicatoin을 debug로 signing할때, "android"란 password를 통해서 생성sign하기때문에, keytool에서도 동일 password를 써줘야 한다.




요새 CoreData 관련 공부에 몰두 하고 있습니다.
이런저런것들을 보고 있는데, CoreData Version Up과 LightWeight Migration에 관련 챕터를보았는데,

Modeling 을 변경했을때 자동으로 Data Migration을 해준다는것입니다 ! 
 
그래서 한번 해보기로 했습니다.

아래는 WWDC 2010 의 "Mastering CoreData" Session의 Slide 캡처 화면입니다.

 
음 샬라샬라~
기존의 모델을 유지하고, Version  올려 주고, Option만 주면 된다는 간략한 내용이군요

기존의 자료 ( Apple의 Core Data Programming Guide 마저도... ) Xcode3기준으로 작성되어 약간의 Editor 사용법이 다르지만, 어렵지는 않습니다.
진행 순서는 아래와 같습니다.

1. 버전 추가
2. Attribute renaming
3. 소스 변경
4. Model Current Version 변경
5. 옵션 추가

1. 버전 추가

 위와 같이 Model Editor에서 Editor->Add Model Version 클릭 해주시면 Version 생성 다이얼로그가 나오고는데 적당한 이름을 사용하시면 됩니다.

2.  Attribute renaming
attribute의 이름을 변경합니다. 저는 createdDate라는 Attribute를 createdDate2로 변경했습니다.
예제를 rename 으로 한데는 이유가 있겠죠, 

rename의 경우 original attribute name을 core data 쪽에 알려줘야합니다.

entity를 선택한후 Data Model Inspector의 "Renaming ID"에 원래 이름을 적어줍니다 저 같은 경우 createdDate가 되겠군요


3. Class 변경

class 의 변수 이름을 createdDate 에서 createdDate2로 변경해줍니다.
Xcode내의 refactoring 기능을 이용하면 한번에 수정가능합니다.

단, NSSortDescriptor나 NSPredicate에서 문자열로 사용한 경우에는 수동으로 찾아서 변경해주어야합니다.

 

 4. DataModel 현재 버전 변경하기


위에서 보시는 바와 같이, Version을 추가하여, 새로 만들었지만, 현재는 예전의 Model을 사용하도록 되어 있습니다. 
Model 파일의 Root(Locations.xcdatamodelId)를 선택한후 File Inspector를 열어서 현재 버전을 세팅 하실수 있습니다.

 변경후의 모습은 다음과 같겠군요


 5. NSPersistentStoreCoordinator Open Option설정하기

기본적으로는 Migration기능이 비활성화 되어 있기 때문에, lightweight migration기능을 사용하기 위해선, 몇가지 옵션을 설정해주어야 합니다.

NSInferMappingModelAutomaticallyOption 과 
NSMigratePersistentStoresAutomaticallyOption 입니다.

코드는 아래와 같겠군요

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,
                             nil];
 
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {}


 
이렇게 하고 실행하시면, 수정된 Model Class로 이전의 Data까지 사용가능하게 됩니다.

별로 어려운건 아닙니다만, 이래저래 개념적으로 확인해야 할것들이 많군요

CoreData는 살펴볼수록 괜찮은 녀석인것 같습니다 ^^ 

settings.py 를 template에서 사용하기 위해서는 기본적으로 context할때 값을 넣어 주는 수 밖에 없다.

    context = {'DEBUG': settings.DEBUG}

 
근데 view에서 매번 이것을 세팅해서 넘겨주는건 좀 아니지 않을까? :)

그래서 context_processor를 사용하여 모든 request의 context에 값을 세팅 할 수 있다.

 myapp/context_processors.py를 아래와 같이 작성하자.

def load_settings(request):

return {'DEBUG':settings.DEBUG} 


그리고 settings.py에 아래와 같이 CONTEXT_PROCESSOR를 등록한다.

 86 TEMPLATE_CONTEXT_PROCESSORS = (

 87         'myapp.context_processors.load_settings',

 88         'django.contrib.auth.context_processors.auth',
89 ) 

 
template에서의 사용법은 아래와 같다.

<div>{{DEBUG}}</div>



application으로 들어오는 모든 request를 Catch하기 때문에, 한번 해두면 어디서든 쓸 수 있다.

 

static file을 DJango Framework에서 사용하기 위한 설정

1. django.contrib.staticfiles app 설정

116 INSTALLED_APPS = (

117     'django.contrib.auth',

118     'django.contrib.contenttypes',

119     'django.contrib.sessions',

120     'django.contrib.sites',

121     'django.contrib.messages',

122     'django.contrib.staticfiles',


 ( default로 포함되어 있다.)

2. STATIC_ROOT 설정

 STATIC_ROOT = '/Users/taehoonkoo/workspaces/work_django/static/'

static file이 모이게 되는 folder

3. STATIC_URL 설정

 STATIC_URL = '/static/'

{{PROJECT_URL}}/static/로 접근이 가능하게 된다.

4. STATICFILES_DIRS

71 STATICFILES_DIRS = (

 72     # Put strings here, like "/home/html/static" or "C:/www/django/static".

 73     # Always use forward slashes, even on Windows.

 74     # Don't forget to use absolute paths, not relative paths.

 75     ("js","/Users/taehoonkoo/workspaces/work_django/testproject/static/js/"),

 76     ("css","/Users/taehoonkoo/workspaces/work_django/testproject/static/css/"),

 77     ("images","/Users/taehoonkoo/workspaces/work_django/testproject/static/images/"),

 78     ("pages","/Users/taehoonkoo/workspaces/work_django/testproject/static/pages/"),

 79 )


prefix를 사용하면, /static/js, /static/images/ 등으로 사용하면 된다.

설정이 잘못되어도, server에 올라 갈때 error가 감지 되지 않기 때문에, 아래와 같은 명령어로 확인할 수 있다.

$ python manage.py collectstatic --help
$ python manage.py findstatic my.js



원문 : https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS

 

1. Create Project

django-admin.py startproject {myproject}
 

2. Development Server

python manage.py runserver.
 

3. Create Default App.

python manage.py startapp polls
  
 


 
 

ids = [1,2,3,4]
MyObject.objects.filter(id__in=ids)


위와 같이 가능하다.
 

referer = request.META.get('HTTP_REFERER', '') 


이건 DJango 라기 보다, HTTP META 스펙일듯.

+ Recent posts