UITableView更新beginUpdates和endUpdates调用之间的更新被批处理,并且所有操作都在同一时间执行.Apple的文档特定于执行顺序insert和delete执行操作:
动画块中的删除和重新加载操作指定应删除或重新加载原始表中的哪些行和部分; insertions指定应将哪些行和部分添加到结果表中.用于标识节和行的索引路径遵循此模型.另一方面,在可变数组中插入或移除项目可能会影响用于连续插入或移除操作的数组索引; 例如,如果在某个索引处插入项,则数组中所有后续项的索引都会递增.
值得注意的是:
可以嵌套对beginUpdates和endUpdates的调用; 所有索引都被视为只有外部更新块.
[ 强调我的 ]
所以:考虑在第一次传递中发生的删除,然后使用删除后产生的新索引路径,然后在此之后发生任何插入.
那很有用.但是,我没有找到任何关于行(和部分)移动发生的位置,应该使用哪种索引以及这是否会影响其他步骤的文档.谁知道?
为了说明这个问题,我在Github上编写了一个非常小的Xcode项目(两个类,11kb下载).看看这里的要点或使用git clone git@gist.github.com:93982af3b65d2151672e.git.
请考虑以下方案.我的自定义视图称为"容器视图",包含两个小方块.截图中显示:

蓝色方块是22x22 pt UIView实例,红色方块是22x22 pt CALayer实例.出于这个问题的目的,我希望两个正方形"粘住"到外部视图的右下角,同时我为该外部视图的框架设置动画.
我在UIView类的方法中更改容器视图的框架animateWithDuration:delay:options:animations:completion:,使用类型的非默认缓动参数UIViewAnimationCurveEaseOut.
[UIView animateWithDuration:1.0 delay:0
options:UIViewAnimationCurveEaseOut
animations:^{ _containerView.frame = randomFrame; }
completion:nil];
Run Code Online (Sandbox Code Playgroud)
注意:蓝色UIView和红色CALayer的框架都在setFrame:容器视图的重写方法中设置,但如果我将蓝色UIView的autoresizingMask属性设置为UIView灵活的左边距和上边距,结果将是相同的.
在生成的动画中,蓝色方块按照我的预期方式"粘贴"到角落,但红色方块完全忽略了动画的时间和缓和.我认为这是因为Core Animation的隐式动画功能,这个功能在很多场合帮助了我.
以下是动画序列中的一些屏幕截图,用于说明两个方块的异步性:

关于这个问题:有没有办法同步两个帧的变化,以便红色CALayer和蓝色UIView都以相同的动画持续时间和缓和曲线移动,相互粘连就好像它们是一个视图一样?
PS当然,两个方块粘在一起所需的视觉效果可以通过多种方式实现,例如,通过使两个层成为CALayers或UIViews,但真正问题所涉及的项目具有非常合理的原因.一个是CALayer,另一个是UIView.
从核心数据编程指南(我的重点):
默认情况下,Core Data 为托管对象类的建模属性(属性和关系)动态创建有效的公共和原始 get和set访问器方法.
虽然我一直在使用核心数据和mogenerator愉快,因为我开始对Objective-C的,我从来没有一起来看看这是什么意思,直到提交的应用得到了拒绝因涉嫌使用私有API的.关于生成setPrimitiveTypeValue:方法的长篇故事,但不是我的问题.
在阅读指南时,我偶然发现了实体属性的公共和原始访问器的概念.另一个引用,但进一步说:
例如,给定与属性的实体
firstName,核心数据自动生成firstName,setFirstName:,primitiveFirstName,和setPrimitiveFirstName:.
什么是原始访问者?是这样你可以直接分配BOOL值,而不是将它包装在NSNumber中吗?如果是这样,为什么会mogenerator已通过生成各种的麻烦了<Attribute>Value,set<Attribute>Value:,primitive<Attribute>Value,setPrimitive<Attribute>Value:存取?
我很困惑,谁能帮助我?
相关问题:
TL; DR:我将哪些XML片段添加到我的TemplateInfo.plist文件中,以便在创建新的Xcode项目时创建第二个编译器目标?
在处理我自己的Xcode项目模板时,我正试图让KIF集成测试以"开箱即用"的方式运行.KIF要求您复制常规目标,然后修改某些属性.这通常是手动完成的,但它既需要时间又会留下误差,而它可以实现自动化.
为清楚起见,我希望自动在此屏幕截图中创建第二个目标:

我对整个模板定制做了很多,但我无法弄清楚如何创建另一个目标,即使模板创建一个用于单元测试,如果你点击该复选框.Apple如何做到这一点?
在我的github存储库中查看模板项目.如果你想看看我正在用KIF做什么(即使对于这个问题的答案,这不是必需的),请查看KIF Integrations.xctemplate文件夹中的plist .
Quick是一种行为驱动的开发测试框架.我想知道为什么这比定期XCTests更好.Nimble只是一个匹配库,但它使得测试很容易阅读,比如期望(13)> 9.
对我而言,Quick提供了一个新的词汇表来编写测试(XCTests没有),并使您专注于编写单元测试.基本上它是TDD的特征诱导路径.当测试失败时,它也更具描述性.
我注意到的另一件事是,如果我想看一个方法做什么,如果我去快速规范我可以很容易地阅读什么是被测试,然后了解更多关于方法而不是写方法的评论.因此,快速规范充当对方法的评论.
关于Quick或BDD还有什么我应该知道的吗?
核心数据驱动应用程序的常见方案是从后备存储中获取唯一对象.如果存在具有特定唯一属性的对象,则返回该对象,如果它不返回新创建的对象.我发现自己一遍又一遍地写同样的东西,所以我用一种方便的方法把它包起来.但这似乎是微不足道的,我在这里重新发明轮子吗?有没有更简单,开箱即用的方法来实现这一目标?
干杯,
EP
+(id)uniqueEntityfForName:(NSString *)name
withValue:(id)value
forKey:(NSString *)key
inManagedObjectContext:(NSManagedObjectContext *)context {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat:[key stringByAppendingString:@" == %@"], value];
NSArray *result = [context executeFetchRequest:request error:nil];
id entity = [result lastObject];
if (entity == nil) {
entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context];
[entity setValue:value forKey:key];
} else {
entity = [result lastObject];
}
return entity;
}
Run Code Online (Sandbox Code Playgroud)
我使用这样的方法:
SomeEntity *entity = [CDUtils uniqueEntityfForName:@"SomeEntity" withValue:@"foo" forKey:@"bar" inManagedObjectContext:context];
Run Code Online (Sandbox Code Playgroud) 在开发一组用于将数值和日期转换为字符串的日期计算和语言规则时,我正在编写断言字符串格式化方法结果的测试.对它的想象断言可能如下所示:
NSAssert([dateString isEqualToString:@"Three days, until 6:00 PM"], @"Date string should match expectation");
Run Code Online (Sandbox Code Playgroud)
但是,由于应用程序已针对多种语言进行本地化,并且我的开发人员也来自不同的语言环境,因此可能会将您的设备或模拟器设置为与为其编写测试的语言环境不同的语言环境.在这样的场景中,dateString可能是这样的内容:
@"Drie dagen, tot 18:00" // the assertion fails
@"Drei Tage, bis 18 Uhr" // the assertion also fails
Run Code Online (Sandbox Code Playgroud)
这可能是也可能不是这些语言环境的正确日期符号,但我的问题所在的部分是,当底层代码使用Apple API时,如何能够运行测试到特定的语言环境:
[NSDateFormatter localizedStringFromDate:date
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterShortStyle];
Run Code Online (Sandbox Code Playgroud)
我想在我的断言中用两种或更多种语言覆盖,例如:
[NSSomething actionToSetTheLocaleTo:@"en_US"];
dateString = ...; // the formatting
NSAssert([dateString isEqualToString:@"Three days, until 6:00 PM"], @"match en_US");
[NSSomething actionToSetTheLocaleTo:@"nl_NL"];
dateString = ...; // the formatting
NSAssert([dateString isEqualToString:@"Drie dagen, tot 18:00"], @"match nl_NL");
Run Code Online (Sandbox Code Playgroud)
谁知道如何实现这种效果?
笔记:
关于这个主题的链接:
cocoa-touch localization objective-c internationalization ios
Xcode习惯将各种(冗余)信息放在它创建的每个代码文件的顶部,包含版权声明,类名,项目名称和客户端名称.无论喜欢与否,一旦你创建了一个新的类"A",然后将它重构为"B",信息就已经错了.评论将继续说这是"啊"或"上午".此外,如果您在下一个项目中重用一个项目中的类,它也会说明错误的项目名称.
//
// A.h
// ProjectName
//
// Created by Author on 19-06-11.
// Copyright 2011 CompanyName. All rights reserved.
//
Run Code Online (Sandbox Code Playgroud)
必须有一个原因,没有多少人抱怨这一点.你有什么方法可以保持标题评论的最新状态?有没有一个工具可以自动纠正它?有隐藏的设置吗?
干杯,EP.
我已经虔诚地做了几年了.检查self调用[super init...]方法后的有效性:
self = [super init];
if (self != nil) {
// initialize
}
return self;
Run Code Online (Sandbox Code Playgroud)
你可以用各种方式做到这一点,因为这个问题很好地总结了,但这个问题是关于语法的,我的是关于概念的.
我最近从一位正在学习Objective-C的同事那里得到了一个问题,他问我"我为什么要测试自我的存在,是不是很明显它在那里?" 而我的简短回答是"错误,是的,那里有可能失败的情况,所以这就是原因." 但是很长的答案是,我真的不明白自己为什么要在任何地方进行测试,因为它可能失败的情况非常罕见.Apple的参考指南告诉我们一些特定情况,例如初始化文件或处理单例时.但这听起来像[super init]s应该起作用的规则是非常罕见的例外.
所以我的问题是:为什么我们总是测试自我的有效性?我们是否只是在任何地方实施它以捕获它发生的那个例外?为什么不跳过整个if (self)事情并初始化我们的对象,如果它成功的机会是100%(或从来没有这种情况)?
PS我意识到这个问题必须是一个骗局,因为它是如此基本,但我的搜索查询还有很多关于初始化语法的其他问题.Dupe链接很受欢迎,欢呼!
在我当前的项目中,几个视图控制器(如vc)生成operation在静态NSOperationQueue上执行的NSOperation对象(如).当操作正在等待或运行时,它将通过委托(报告operation.delegate = vc未保留)向视图控制器报告.
这些操作可能需要一段时间,同时应用程序可以取消分配视图控制器(通过弹出导航控制器的堆栈).
到目前为止,一切都是故意的.包含静态NSOperationQueue的类有一种方法可以返回操作,因此视图控制器不会保留它们.它们只是alloc/init/autoreleased并放入队列.
现在这也导致了这个问题.在视图控制器解除分配后,对NSOperation的激烈委托的任何调用都将导致错误的访问冲突.根据我的理解,无法检查指针上的对象是否已被解除分配,如本问题所述.
我能想到的一个修复是保留操作并在dealloc上将operation.delegate设置为nil.但这是我最不受欢迎的解决方案,因为它会引入许多额外的ivars /属性来跟踪.
因此,我的问题是,有没有其他方法可以解决这个问题,如果是这样,你能在这里草拟一个吗?
干杯,
EP.
解决方案:对我来说最好的方法是对Guiliano的回答略有不同:
在队列管理器中实现每个委托协议是不可行的(20多种不同的协议,使用50多种方法),因此我保留了直接委托分配.我改变的是进行分配呼叫的班级.这曾经是创建请求的类(和委托),但现在它被卸载到队列管理器.
除了将委托分配给操作之外,队列管理器还拥有辅助可变字典以跟踪委托/操作对.
每个委托实例都会调用一个[QueueManager invalidateDelegate:self]deallocation方法,然后查找属于该委托的请求并将其取消.然后还删除字典操作/委托对以允许适当地重新分配操作.
最后,当KVO观察isFinished每个操作的属性时,可变dict保持清洁,以确保所有操作保留计数在它们完成后实际解除分配.
感谢Guiliano提供使用KVO破解这一点的提示!
exc-bad-access delegation objective-c nsoperation nsoperationqueue
objective-c ×8
cocoa-touch ×3
ios ×3
cocoa ×2
core-data ×2
xcode ×2
bdd ×1
comments ×1
delegation ×1
localization ×1
mogenerator ×1
nsoperation ×1
quick-nimble ×1
uitableview ×1
unique ×1