2014-08-24

dispatch_group_enterとdispatch_group_leaveの呼び出し回数が揃ってないとクラッシュ?

dispatch_group_enterとdispatch_group_leaveの呼び出し回数が揃ってないとクラッシュするという、えー、それホント?的な質問がstack overflowに上がってました。

Why is it necessary to call dispatch_group_leave the same number of times as dispatch_group_enter?

こんなコードを試してみると、実際クラッシュ (要ARC)。

/* test.m */
#include <dispatch/dispatch.h>

int main()
{
    {
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_enter(group);
        //dispatch_group_leave(group);
    }
    return 0;
}

dispatch_groupはdispatch_semaphore使ってて、dispatch_semaphoreはsignalとwaitの呼び出し回数が揃ってない状態でdispatch_releaseするのは禁止(実装上そーなってて強制クラッシュされる)。てな感じでした。

Tumblrから帰ってきてみた

Google Domains移転記念に、TumblrからBloggerに帰ってきてみた。なんかblog投稿とは別にページ作れるようになってたり、いろいろ変わってた。

2011-05-03

いまどきの2Dゲームエンジン

スクリプト言語でiPhoneやAndroid用ゲームを作れる2Dゲームエンジンをまとめてみる試み。


name Corona moai Imapct Kobold2D
link
link
link
link/iOSImpact
link
desc
Corona is the world’s most advanced mobile development platform.
The mobile platform for pro game developers.
Impact is a JavaScript Game Engine that allows you to develop HTML5 Games in no time.
Kobold2D™ is the expert's choice for Cocos2D game development.
license proprietary OpenSource
(CPAL)
proprietary OpenSource
(MIT License)
language Lua Lua Javascript Lua
native ?(C++) C++ ?(Objective-C) Objective-C
iOS available available available available
Android available available not yet -
price $199/year Free $99 Free
release released private beta beta 2011 summer

2011-03-30

MacVim-KaoriYa 20110330

MacVim-KaoriYa 20110330版をリリースしました。

今回はSparkleによる自動更新を設定していません。(2011/04/01 Sparkle情報を更新しました)

http://code.google.com/p/macvim-kaoriya/

http://macvim-kaoriya.googlecode.com/files/macvim-kaoriya-20110330.dmg

Xcode 4でビルドしています。

Mac OS X 10.5 Leopardを使用されている方、Intel、PowerPC 問わず、動作確認にご協力いただけますと幸いです。

Vim 7.3.146、MacVim Snapshot 57、香り屋パッチ 20110323ベースです。


(2011/04/01 追記)
実験的レンダラを使用していない場合、半透明設定(set transparency)が効かなくなります。半透明設定を使用している場合は、「環境設定」「詳細」の「実験的レンダラを使用する」「インラインインプットメソッドを使用する」の両方をチェックしてみてくださいませ。

2011-03-25

Xcode4でPowerPC


$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /Developer/usr/libexec/gcc/darwin
$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /usr/libexec/gcc/darwin


Xcode 4.0.1でも治ってませんでした。バグレポート忘れてたんですが。

これやっとくと、MacPortsでLeopard用のuniversal buildも可能になります。


$ sudo port install ncurses +universal macosx_deployment_target=10.5 configure.cc=/usr/bin/gcc-4.2 configure.cxx=/usr/bin/g++-4.2

『iOS 4プログラミングブック』 第5章マルチスレッド 補遺 その8



本屋にも並んでます『iOS 4プログラミングブック』。

補遺その8、というか、間違いのお知らせです。ごめんなさい。

iOS 4プログラミングブック 第5章
190ページ 図5-2-5「ヒープからヒープへのコピー」の先頭行に間違いがあります。

(誤) block_t block3_on_heap = Block_copy(block_on_stack);
(正) block_t block3_on_heap = Block_copy(block_on_heap);


@eyesrobe様に発見していただきました。ありがとうございます。

2011-03-03

『iOS 4プログラミングブック』 第5章マルチスレッド 補遺 その7



そろそろ浸透して話題にも上がらなくなってきた(?)『iOS 4プログラミングブック』。

補遺その7では、BlocksのObjective-C支援機能に切り込んでみます。

191ページに書いてあるとおり、Objective-Cのオブジェクトは、Block_copy時に自動的にretainされます。


NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *string = [NSString stringWithFormat:@"score = %d", score];

void (^block)() = Block_copy(^{

NSLog(@"%@", string);

});

[pool drain];

/* stringはblockからretainされてるから、まだ生きてる */



これどういう仕組みなんでしょう?


Objective-Cのオブジェクトは、みなNSObjectの子供。

NSObjectは、C言語としては、__attribute__((NSObject))アトリビュートの付いた変数。


てことで、Block_copy時に__attribute__((NSObject))のついた変数をretainして、Block_release時にreleaseするコードを、コンパイラは簡単に生成できるわけですね。


http://clang.llvm.org/docs/Block-ABI-Apple.txt
2.2.1 Importing __attribute__((NSObject)) variables.



しかし、この自動retainする機能。便利なのはいいのですが、実は気づかないうちに、循環参照してdeallocされない状況に陥ることもある諸刃の剣。

Blockが、Blockをretainしているクラスのselfを自動retainしちゃう、という落とし穴。

詳しくは『iOS 4プログラミングブック』の193ページに!

2011-02-08

OpenGL ES 開発リソースまとめ

GPU作ってるとこのOpenGL ES 1.1/2.0開発リソースが、実は大変充実しています。まとめてみました。

■POWERVR Insider http://www.imgtec.com/powervr/insider/powervr-insider.asp

□主な使用機種: iPhone 3G(MBX),DROID(SGX530),iPhone 4/iPad(SGX535),Nexus S/Galaxy S(SGX540),NGP(SGX543),...

・POWERVR Insider SDK。COLLADAから変換したPOD形式を使って3Dモデルの描画、アニメーション可能。ソースコードのライセンスは非常にゆるい(forumのSDK Code Licenseスレッド参照)。

・PowerVR圧縮テクスチャPVR用コンバータ PVRTexToolなどのツールも充実。

■ADRENO GRAPHICS http://developer.qualcomm.com/dev/gpu

□主な使用機種: Xperia,Nexus One,Desire,IS03,Regza,Windows Phone 7...

・Adreno™ Profilerが凄い。rootとったNexus OneなどをUSBケーブルで繋ぐだけで、リアルタイムにGPUの負荷やテクスチャ、描画結果を取得可能。

・Adreno向けに最適化されたOpenGL ES 2.0 shader source codeあり。でもOpenGL ES 2.0であればどこででも。

■TEGRA DEVELOPER ZONE http://tegradeveloper.nvidia.com/tegra/

□主な使用機種: dynabook AZ,各種タブレット,...

・Android NDK用のサンプルコードはApache License 2.0。JNI経由で音を鳴らす方法なども含んでいるので、NDKで開発する場合は必見。

・EclipseでNDKをデバッグするためのNVIDIA Debug Manager for debugging Android NDK applications in Eclipse とかあったりする。

■Mali Developer Center http://www.malideveloper.com/index.php

□主な使用機種: コンシューマ製品があるかどうか不明

・Mali GPU Shader Development Studio。IDE的に結果をみながらshader開発が可能。


また各サイトでWindowsやLinux用のOpenGL ES 1.1/2.0 emulator libraryが配布されてますので、iPhoneやAndroid向けに作ったOpenGL ES 1.1/2.0用のソースコードを、WindowsやLinux用にビルドして実行することが可能です。

各GPUごとの開発リソースは大変特色が出ているのですが、OpenGL ES 1.1/2.0経由で使うことになりますので、profilerなど専用なもの以外は、どれででも使えてしまいます。便利に使っちゃいましょう。

2011-02-03

『iOS 4プログラミングブック』 第5章マルチスレッド 補遺 その6



楽天BOOKSで一時売り切れになるも、再度入荷中の『iOS 4プログラミングブック』。Amazonでは相変わらず在庫切れ...

補遺その6では、ちょっと趣向を変えてサンプルコードを説明してみます。

第5章マルチスレッドのサンプルコードは、実はTumblr Image Viewerになっていたり、cocos2d for iPhoneを使っていたりする、実戦さながらのサンプルコードとなっております。

今回はcocos2dでの非同期テクスチャ読み込みについて掘り下げてみます。


cocos2dの非同期テクスチャ読み込みAPIは、読み込み終了時にtargetのselectorを呼ぶコードになっています。これBlocksだと楽になるような気がしませんか? Blockを受け取って呼び出すClassを作ってみます。

■TextureCallback.h

/*
* 「5-1 Blocksの概要」(178ページ)
* TextureCallbackクラスにより、
* cocos2dのイメージ非同期読み込み終了コールバックを、
* Blocksに結びつけることにより、より簡単にコールバックを記述できます。
*/

#import "cocos2d.h"

/*
* 「5-2-2 値としてのBlock」(184ページ)
* typedefを使用したBlocksの宣言。
*/
typedef void (^textureCallbackBlock_t)(CCTexture2D *texture);

@interface TextureCallback : NSObject
{
textureCallbackBlock_t block_;
}

/*
* イメージ非同期読み込み終了コールバックで実行されるBlockを指定。
*/
+ (id)callbackWithBlock:(textureCallbackBlock_t)block;
- (id)initWithBlock:(textureCallbackBlock_t)block;
- (void)callback:(CCTexture2D *)texture;

@end


■TextureCallback.m

#import "TextureCallback.h"

@implementation TextureCallback

+ (id)callbackWithBlock:(textureCallbackBlock_t)block
{
return [[[self alloc] initWithBlock:block] autorelease];
}

- (id)initWithBlock:(textureCallbackBlock_t)block
{
if ((self=[super init])) {

/*
* 「5-2-4 Block_copy」(188ページ)
* 渡されたBlockをretainするためにObjective-Cのcopyを使用。
*/
block_ = [block copy];
}

return self;
}

- (void)dealloc
{

/*
* 「5-2-4 Block_copy」(188ページ)
* retainしたBlockをreleaseするためにObjective-Cのreleaseを使用。
*/
[block_ release];
[super dealloc];
}

- (void)callback:(CCTexture2D *)texture
{
/*
* 「5-2-2 値としてのBlock」(184ページ)
* cocos2dのイメージ非同期読み込み終了時Blockを実行。
*/
block_(texture);
}

@end


て感じで。使うときは


#import "TextureCallback.h"

/*
* 非同期イメージ読み込み終了時に
* 実行されるBlockを指定。
*/
TextureCallback *textureCallback =
[TextureCallback callbackWithBlock:
^(CCTexture2D *texture) {

[self addTexture:texture index:index];

}];

/*
* cocos2dの非同期イメージ読み込み
* (要メインスレッド(Main Queue))
*/
[[CCTextureCache sharedTextureCache]
addImageAsync:path target:textureCallback
selector:@selector(callback:)];



さらに、


+ (id)addImageAsyncWithBlock:(NSString *)path block:(textureCallbackBlock_t)block
{
id textureCallback = [[[self alloc] initWithBlock:block] autorelease];

[[CCTextureCache sharedTextureCache]
addImageAsync:path target:textureCallback
selector:@selector(callback:)];

return textureCallback;
}


こんな感じのクラスメソッドにすれば、


#import "TextureCallback.h"

/*
* 非同期イメージ読み込み終了時に
* 実行されるBlockを指定。
*/
[TextureCallback addImageAsyncWithBlock:path block:^(CCTexture2D *texture) {

[self addTexture:texture index:index];

}];


あらすっきり。


CCTextureCacheは渡ってきたtextureCallbackをコールバック終了までretainするので、コールバック終了までちゃんと生存。textureCallbackで持つことになるblockもtextureCallback生存中はretain(copy)されるので、メモリ管理も簡単、安心。


iOS 4プログラミングブックのサンプルコードは、http://www.impressjapan.jp/books/2976のダウンロードよりどうぞー