我正在编写一个需要加密数据的iPhone应用程序.我已经学会了如何通过设置NSFileProtectionComplete属性来打开文件加密.我也知道如何检查iPhone版本以确保它们运行的是iOS 4.0或更高版本.
我已经意识到,如果用户没有选择密码并且没有在设置>常规>密码锁屏幕上专门启用数据保护,那么数据实际上根本不受保护.
我想弹出警告并告诉用户他们必须启用密码并启用数据保护(这需要在4前iPhone上进行备份和恢复),然后如果他们没有密码则退出应用程序并启用数据保护.我无论如何都无法弄清楚这些设置的状态.我发现的所有API,例如UIApplication中的"protectedDataAvailable",如果禁用数据保护,都会成功通过.
这是一个例子:
假设我有一个Student对象,它与ReportCard对象有一个has_many关系.ReportCard对象有一个名为"graded"的布尔字段,标记它们已被评分.所以它看起来像:
class Student < ActiveRecord
has_many :report_cards
end
class ReportCard < ActiveRecord
# graded :boolean (comes from DB)
belongs_to :student
end
Run Code Online (Sandbox Code Playgroud)
现在,假设你要创建一个默认范围,这样如果学生没有评分的报告卡,你想看到所有这些,但如果他们至少有一个评分的ReportCard,你只想看到评分的.最后,假设您按"semester_number"命令它们.
在ReportCard上使用此范围正常工作:
scope :only_graded_if_possible, ->(student) { where(graded: true, student: student).order(:semester_number).presence || order(:semester_number) }
Run Code Online (Sandbox Code Playgroud)
但我希望它成为学生的默认范围,所以我试过:
class Student < ActiveRecord
has_many :report_cards, ->{ where(graded: true).order(:semester_number).presence || order(:semester_number) }
end
Run Code Online (Sandbox Code Playgroud)
但这不起作用.如果整个数据库中只有一个分级的report_card,它将不会返回任何report_cards.查看运行的查询,首先它运行如下:
SELECT report_cards.* FROM report_cards WHERE reports_cards.graded = t ORDER BY semester_number ASC
Run Code Online (Sandbox Code Playgroud)
我认为这一定是礼物吗?检查存在查询的一部分,并注意它根本不过滤学生!因此,如果有一个评分的report_card,则检查通过,然后运行以下查询以获取返回的内容:
SELECT report_cards.* FROM reports_card WHERE report_card.student_id = 'student id here' AND report_card.graded = t ORDER BY semester_number …Run Code Online (Sandbox Code Playgroud) 比方说,例如,您正在编写一个等待队列中的消息,处理它,然后等待下一条消息的程序,这将永远持续下去.在像C或Java这样的语言中,它看起来像这样:
void processMessage() {
while (true) {
// waitForMessage blocks until the next message is received
msg = waitForMessage();
// handle msg here
}
}
Run Code Online (Sandbox Code Playgroud)
在Javascript(我使用node.js,顺便说一句),因为使用了回调,它通常看起来像这样:
function processMessage() {
waitForMessage(function(msg) {
// handle msg or error here
processMessage();
});
}
Run Code Online (Sandbox Code Playgroud)
我担心你基本上有一系列回调函数递归调用原始函数,这样做的开销可能会慢慢耗尽内存.我猜这不是一个问题,因为也许javascript回调独立存在于他们自己的堆栈上并且不会被推到原始函数的堆栈中?有人向我解释了javascript回调和范围,并向我保证,当收到任意大量的消息时,javascript代码在任意长时间运行时不会耗尽内存
我试着仿效iPhone上Apple的邮件应用程序中的"新消息"页面.我用tableview实现了它,并且我已经成功地获得了"To","CC"和"Subject"行以正常运行,但我不确定如何实现页面的实际消息部分.
我有几个问题.我正在尝试通过在单元格中放置UITextView来实现它(我关闭了文本视图上的滚动条).通过将文本框架修改为内容的新高度,我可以在文本视图更改时自行调整大小.第一个问题是我还需要为单元格高度本身做这个.由于heightForRowAtIndexPath似乎只在第一次加载行时被调用,所以我无法修改那里的高度.我想我可以在表上调用重载数据,但这似乎每次输入文本时在整个表上都是非常低效的.在用户输入时让表格单元格自动调整大小的最佳方法是什么?我已经找到了很多关于如何在单独的表视图上执行此操作以及如何在初始化时调整表单元格大小的示例但我可以'
最后,我希望表格单元格的底部边框不可见.如果您查看邮件应用程序,您会注意到邮件空间底部没有任何行,这意味着您可以继续输入.我总是在我的表视图中有一个(即使我添加页脚),我也无法弄清楚如何摆脱它.(也许我应该让我的信息主体成为页脚本身?)
我正在使用Bluebird promise库.我有一系列有保证的功能,如下所示:
receiveMessageAsync(params)
.then(function(data)) {
return [data, handleMessageAsync(request)];
})
.spread(function(data, response) {
return [response, deleteMessageAsync(request)];
})
.spread(function(response, data) {
return sendResponseAsync(response);
})
.then(function(data) {
return waitForMessage(data);
})
.catch (function(err) {
// handle error here
});
Run Code Online (Sandbox Code Playgroud)
偶尔sendMessage会失败,因为,假设要响应的服务器不可用.我希望代码能够继续尝试永远响应,直到成功为止.你不能简单地将sendMessage包装在一个catch中,因为它实际上并没有抛出异常,我想,它调用了"error"函数,在这个promisified代码中,它是底部的"catch".因此必须有一些方法可以在"catch"部分"重试"发送消息.问题是,即使我在"catch"中循环重试,我仍然没有办法跳到promise链并执行剩余的promisified函数.我该如何处理?
编辑:
我对HTTP帖子的重试最终看起来像这样:
function retry(func) {
return func()
.spread(function(httpResponse) {
if (httpResponse.statusCode != 200) {
Log.error("HTTP post returned error status: "+httpResponse.statusCode);
Sleep.sleep(5);
return retry(func);
}
})
.catch(function(err) {
Log.err("Unable to send response via HTTP");
Sleep.sleep(5);
return retry(func);
});
}
Run Code Online (Sandbox Code Playgroud) 假设我有"obj"类型的核心数据对象,它具有属性"propertyA"和与"sub"类型的对象的一对多关系,该对象具有两个属性"propertyB"和"propertyC".
我想获取propertyA等于一个值的所有objs和一个带有propertyB和propertyC set的子obj.
如果它只是propertyA和propertyB,我会这样做
[NSPredicate predicateWithFormat:@"ANY sub.propertyB = %@ AND propertyA == %@", ...];
Run Code Online (Sandbox Code Playgroud)
问题是我无法弄清楚如何添加第二个属性.我只想要至少有一个具有两个属性的子的obj.我尝试了以下,但它不起作用:
[NSPredicate predicateWithFormat:@"ANY (sub.propertyB = %@ AND sub.propertyC) AND propertyA == %@", ...];
Run Code Online (Sandbox Code Playgroud)
我已经尝试过没有ANY,但这也不起作用.我怎样才能做到这一点?
假设你从一个UIImage开始,你想要裁剪它.最常见的方法是使用CGImageCreateWithImageInRect来获取CGImageRef并从中创建一个新图像,如下所示:
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
Run Code Online (Sandbox Code Playgroud)
现在让我们说你以后需要将这个UIImage转换为NSData对象.例如,如果您希望使用NSKeyedArchiver将映像存储在磁盘上,则会发生这种情况.或者,您可以通过以下显式执行以下操作来获取NSData对象:
NSData *imageData = UIImagePNGRepresentation(croppedImage);
Run Code Online (Sandbox Code Playgroud)
我做了这个,后来我尝试通过以下方式重建一个新的UIImage对象:
UIImage *image = [UIImage imageWithData:imageData];
Run Code Online (Sandbox Code Playgroud)
我为一系列48张图片做了这个.他们中的大多数都很好,但是在每4张图片之后,接下来的两张图片都被破坏了,每张图片的顶部和底部都被交换了.如果我将转换转换为NSData并再次返回,它可以正常工作.如果我使用NSKeyedArchiver将图像数组写入磁盘(我猜它在其编码例程中调用类似UIImagePNGRepresentation的东西),我也会得到完全相同的问题.我的理论是这必须与我如何从CGImageRefs构建图像有关.
这是什么解决方法?我似乎无法弄清楚如何将CGImageRefs放入NSData对象,我更喜欢一个正确构建UIImage的解决方案,以便它可以被序列化.
编辑:
有些人要求运行实际的代码,所以我在这里添加它
UIImage *image = self.animationObject.image;
for (int y=0; y<[self.animationInfoObject.numInY intValue]; y++) {
for (int x=0; x<[self.animationInfoObject.numInX intValue]; x++) {
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
NSData *imageData = UIImageJPEGRepresentation(croppedImage, 1.0);
[self addImageToArray:imageData];
CFRelease(imageRef);
}
} …Run Code Online (Sandbox Code Playgroud) 我很难将m个核心数据对象解除分配.我甚至尝试过我能想到的最简单的测试,并且我看到了保留计数,它似乎总是高于我的预期.我还在核心数据对象的dealloc例程上设置了一个断点,它似乎没有被调用(至少除非我专门添加其他版本).
顺便说一句,我肯定有[managedObjectContext setRetainsRegisteredObjects:NO],所以这不是问题.
这是我尝试过的一个不起作用的例子:
MobileObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"MobileObject" inManagedObjectContext:managedObjectContext];
NSLog(@"Object count after creation %d", [obj retainCount]);
NSError *error;
[managedObjectContext save:&error];
NSLog(@"Object count after saving %d", [obj retainCount]);
Run Code Online (Sandbox Code Playgroud)
每条日志消息都打印出"2".Dealloc永远不会被召唤.我希望save能够释放(或自动释放)对象,因为核心数据应该意识到它不需要保持不变.在这种情况下,如果有两个自动释放(一个来自创建,一个来自保存),则保留计数为2是有意义的,但似乎并非如此.如果我加
[obj release]
Run Code Online (Sandbox Code Playgroud)
在我测试的最后,dealloc例程将被正确调用,但我很困惑为什么我需要这个版本.
核心数据在iPhone上的表现绝对是悲惨的.索引是完全破坏还是只是一个糟糕的实现?
我的核心数据存储(SQLite后备存储)中有大约21500个单一类型的对象.对象在UUID上索引,UUID是NSString(例如,一个看起来像这样:"6b09e200-07b6-11df-a245-002500a30d78").
使用NSManagedObjectContext中的executeFetchRequest对象存在的单个提取大约需要0.75秒!这是最简单的谓词"uuid == $ UUID",其中$ UUID是一个类似上面例子的字符串.
这真的很令人惊讶.如果我想逐个获取商店中的每个对象,则需要将近4.5小时!
反正有没有改善这种性能,还是我应该放弃核心数据?
我有一个经过验证可以正常工作的 Lambda 函数。我可以使用“update-function-code”在命令行上手动更新函数,但我一直试图让它与代码管道和云形成一起工作。以下是我到目前为止的步骤:
我的 samTemplate.yml 看起来像这样:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: My Lambda function
Resources:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: MyLambdaExecute
Description: My Lambda function
Handler: myhandler.handler
Runtime: nodejs6.10
CodeUri: s3://mybucket/mydirectory/mylambdacode.zip
AutoPublishAlias: Staging
Timeout: 30
DeploymentPreference:
Type: AllAtOnce
如果名称为“MyLambdaExecute”的 lambda 函数不存在并且我将代码推送到 github,则它可以完美运行。但是,如果我修改一些代码并再次推送,它会运行前两个步骤,然后生成一个带有状态的空更改集:
失败 - 不执行更新。
我不确定我必须做什么才能让它发布新版本。我如何让它意识到它需要创建一个新的变更集?
amazon-web-services aws-cloudformation aws-lambda aws-codepipeline
很多应用程序似乎都这样做.例如,转到Apple的邮件应用程序,然后按工具栏上的"回复"按钮.您将获得一个菜单,其中的按钮会显示"回复","全部回复","转发"和"取消",这些按钮将从底部向上滚动.
我想这样做的方法是在IB中使用我想要的按钮创建一个短视图,以模态方式呈现它,并且右视图控制器来处理按钮.
看起来这很常见,必须有一种更简单的方法(比如添加到工具栏和导航栏是多么容易).
我缺少一些小部件或快捷方式吗?
我只有一个托管对象上下文.
我已经修改了托管对象库.
我想在每个托管对象中添加某些字段.将它们一个一个地添加到系统中的每个对象都需要花费太多时间,因此我决定以编程方式将它们添加到托管对象模型中.在应用程序委托中,我首先做:
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
Run Code Online (Sandbox Code Playgroud)
然后我遍历模型中的所有实体并修改它们并为每个实体设置新的属性数组:
for (NSEntityDescription *entity in entities) {
NSAttributeDescription *idAttribute = [[NSAttributeDescription alloc] init];
[idAttribute setName:@"id"];
[idAttribute setAttributeType:NSStringAttributeType];
[idAttribute setOptional:NO];
[idAttribute setIndexed:YES];
Run Code Online (Sandbox Code Playgroud)
等等.
它似乎工作得很好.当我尝试将对象添加到我创建的新的一对一关系时,我遇到了问题.我从同一个托管对象上下文创建对象:
self.action = [NSEntityDescription insertNewObjectForEntityForName:@"MobileObjectAction" inManagedObjectContext:managedObjectContext];
self.user = [NSEntityDescription insertNewObjectForEntityForName:@"MobileUser" inManagedObjectContext:managedObjectContext];
Run Code Online (Sandbox Code Playgroud)
当我到达
[user setAction:action];
Run Code Online (Sandbox Code Playgroud)
我得到:由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'非法尝试在不同上下文中的对象之间建立关系'动作'...
我究竟做错了什么?
这是一个有趣的问题.我有一个视图控制器,我们称之为MyViewController.其中一个成员是自定义视图,我们称之为MyCustomView.MyCustomView还具有对其父MyViewController的引用,因为MyViewController用作自定义视图的委托.卸载MyViewController时出现问题,比如由于内存警告.这是发生的事情:
首先,为MyViewController调用viewDidUnload.它看起来像这样:
- (void)viewDidUnload {
[super viewDidUnload];
self.myCustomView = nil;
self.someData = nil;
...
}
Run Code Online (Sandbox Code Playgroud)
当self.myCustomView = nil被执行时,它会触发myCustomView被释放.MyCustomView的dealloc例程看起来像这样:
- (void)dealloc {
...
[delegate release];
...
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
回想一下,委托是MyViewController.如果首先发布MyCustomView,这不会有问题,因为MyViewController的引用计数大于1,但在这种情况下,MyViewController已经没有其他引用了.这会导致MyViewController被释放,即调用dealloc例程,如下所示:
- (void)dealloc {
[myCustomView release];
[somedata release];
...
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,MyViewController的成员,即"somedata"在MyViewController的viewDidUnload例程完成之前就会被释放.随着MyViewController和MyCustomView的dealloc例程完成,我们回到完成viewDidUnload例程,我们到达该行
self.somedata = nil;
Run Code Online (Sandbox Code Playgroud)
现在,有些数据不是零,但它的价值已经被释放了!这会导致异常.
这似乎是引用计数中的一个关键缺陷.你如何处理这样的对象中的双向引用,导致彼此被释放?
一个答案是始终在dealloc例程中将成员设置为nil.我不喜欢那个答案.这是一项额外的工作,大部分时间都不需要.另一个答案是重新排列viewDidUnload的顺序,以便可能具有向后指针的子对象的释放总是在最后发生.我也不喜欢这种解决方案,有时甚至可能都无法工作.
你是如何解决这个问题的?
iphone memory-management objective-c uiviewcontroller didreceivememorywarning
iphone ×7
core-data ×5
objective-c ×3
javascript ×2
node.js ×2
activerecord ×1
aws-lambda ×1
bluebird ×1
callback ×1
cgimageref ×1
encryption ×1
has-many ×1
ios ×1
ios4 ×1
memory-leaks ×1
nsdata ×1
nspredicate ×1
promise ×1
recursion ×1
ruby ×1
scope ×1
uiimage ×1
uitableview ×1
uitextview ×1