我正在创建一个由不同游戏板组成的游戏,这些游戏板作为字典存储在一个数组中,存储在json文件中。 json文件非常大,数组中有超过3,000个对象,大小约为23mb。我此刻加载此文件的方式是在appDelegate实现文件中的didFinishLaunchingWithOptions中,如下所示:
NSString * filePath =[[NSBundle mainBundle] pathForResource:@"words" ofType:@"json"];
NSError * error;
NSString* fileContents =[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
if(error)
{
NSLog(@"Error reading file: %@",error.localizedDescription);
}
NSDictionary *data = (NSDictionary *)[NSJSONSerialization
JSONObjectWithData:[fileContents dataUsingEncoding:NSUTF8StringEncoding]
options:0 error:NULL];
wordsArray = [[NSMutableArray alloc]initWithArray:[data objectForKey:@"results"]];
然后我可以通过调用:
从应用程序的任何位置检索数组NSArray *wordsArray = appDelegate.wordsArray;
除了应用程序在iPhone 4设备上加载花费超过15秒这太长时间之外,它的效果很好,而且我知道应用程序可能因为加载时间过长而被拒绝。
有人可以提出一个更好的方法来解决这个问题,
感谢
答案 0 :(得分:3)
使用核心数据之类的东西。它专为存储此类信息而设计。
另外,不要把它交给APP代表!应用程序代表可以响应应用程序事件。它不是您的应用所需的所有数据的转储。
答案 1 :(得分:2)
设置带有加载程序的输入屏幕(为用户做一个有趣的加载程序......)并在此屏幕上加载数据。完成后,启动游戏......
答案 2 :(得分:2)
根据Yedidya的建议,您可能希望展示一些有趣的内容以保持用户参与。
最重要的是,最重要的是:
public Bitmap compressImage(String imageUri) {
String filePath = imageUri;
// String filePath = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not
// loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as
// 816x612
/*
* float maxHeight = 816.0f; float maxWidth = 612.0f;
*/
float maxHeight = 1080.0f;
float maxWidth = 800.0f;
float imgRatio = actualWidth / (float) actualHeight;
float maxRatio = maxWidth / (float) maxHeight;
// width and height values are set maintaining the aspect ratio of the
// image
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
// setting inSampleSize value allows to load a scaled down version of
// the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth,
actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low
// on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
bmp = BitmapFactory.decodeFile(filePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,
Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2,
middleY - bmp.getHeight() / 2, new Paint(
Paint.FILTER_BITMAP_FLAG));
// check the rotation of the image and display it properly
ExifInterface exif;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
Log.d("EXIF", "Exif: " + orientation);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
true);
} catch (IOException e) {
e.printStackTrace();
}
return scaledBitmap;
}
或performselectorOnBackground
之一执行后台任务。 dispatch_async(some_global_queue)
或performselectorOnMainThread
返回主屏幕/游戏用户界面。答案 3 :(得分:1)
Apple有许多指南可以帮助您:
通常,性能是App设计的产品,因此为了提高性能,您可能需要重新设计应用程序的大部分内容。
我会按照以下步骤操作:
答案 4 :(得分:1)
根据Yedidya的建议,您可能希望展示一些有趣的内容以保持用户参与。
最重要的是,最重要的是:
performselectorOnBackground
或dispatch_async(some_global_queue)
之一执行后台任务。 performselectorOnMainThread
或dispatch_asynch(dispatch_get_main_queue)
返回主屏幕/游戏用户界面。这是要点:
//START BUSY CURSOR HERE
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
// Read JSON file here
dispatch_async(dispatch_get_main_queue(),
^{
//STOP BUSY CURSOR
//PERFORM UI UPDATE HERE
});